1-Sep-80 02:29:00,415;000000000000 Date: Monday, 1 September 1980 02:29-MDT From: MCTESQ at MIT-MC (Michael Toy) To: INFO-CPM at MIT-MC Subject: Well I just started using CP/M today... And its not that bad. I'd rather have unix or even tops (bottoms?) 10, but its better than i thought. Is there some reason for the stat command to not work? It just starts printing garbage over and over and i don't understand why. michael 1-Sep-80 02:39:00,683;000000000000 Date: Monday, 1 September 1980 02:39-MDT From: MCTESQ at MIT-MC (Michael Toy) To: INFO-CPM at MIT-MC Subject: How do you ... I have a lot of programs on cassete that sit at location 0. Is there any way other than writing a program that loads them from disk to run them under cp/m? FJW, yes I exit programs in a way other than jmp 0, i pop h at the beginning of my program and shld it someplace, then to quit i lhld it back and do a pchl. Or I'll just save the CCP stack pointer, set up my own stack, then restore the CCP stack before I quit so I can go back with a ret. This keeps the disk from clicking on at then end of every program i write. michael 1-Sep-80 03:01:00,999;000000000000 Date: Monday, 1 September 1980 03:01-MDT From: Frank J. Wancho To: MCTESQ at MIT-MC cc: INFO-CPM at MIT-MC Subject: How do you ... Loading from disk would solve the problem that CP/M wants the program to start at 0100H. You will need to reassemble with ORG 0100H and write a program which relocates itself to high memory and reads the cassette programs into 0100H and then JMP 0100H. I also save the CCP SP and end up with a RET as follows: START LD (EXITX),SP LD SP,MYSTACK , , EXIT LD SP,0 EXITX EQU $-2 RET However, I don't save on the click because I may have done some disk I/O from the time I left, and thus I do a RESET and SELDSK of the saved default drive. So, in my case, I could probably cut all that out and just do a JP 0 to get the same effect, right? If your disk I/O works then the STAT should also work. What is your configuration? Did you have to do anything special to bring up your CP/M in the first place? --Frank 1-Sep-80 03:04:00,223;000000000000 Date: Monday, 1 September 1980 03:04-MDT From: Frank J. Wancho To: INFO-CPM at MIT-MC Subject: Another typo Last message should read: Loading the program from disk will NOT solve the problem... 2-Sep-80 00:34:00,711;000000000000 Date: Tuesday, 2 September 1980 00:34-MDT From: Frank J. Wancho To: INFO-CPM at MIT-MC Subject: A MENU Program for CP/M I transcribed and debugged the MENU program described in the Creative Computing article previously cited and the source is now in MC:FJW;MENU MAC in Z80 format (easily reverted to 8080 code) and suitable for input to MACRO-80. (I dumped it at a painful 300 baud for reliability, and read it back in and assembled, linked, and ran it with no errors.) Suggested enhancements: 1. Should list all COM files from all available disks. 2. Should be able to run from any drive. You are welcome to it. (FTP from MC does not require an account.) --Frank 2-Sep-80 15:20:00,218;000000000000 Date: Tuesday, 2 September 1980 15:20-MDT From: MAZE at MIT-DMS (James Mazer) To: INFO-CPM at MIT-MC Does anyone have the documentation on cp/m stored on-line anywhere? Replies to Maze at MC pls. /Jamie 3-Sep-80 21:51:00,1149;000000000000 Date: Wednesday, 3 September 1980 21:51-MDT From: Frank J. Wancho To: INFO-CPM at MIT-MC Subject: List Repaired Apparently the list got reverted to some previous version and has now been brought back up-to-date. Some of you may have missed some correspondence since I do not know how long the list was broken. Here is a summary of the current contents of MC:FJW;CPM ARCHIV (FTPable from MC - no account required): No. Lines From->To Subject or Text 1: 9 MAZE->INFO-CPM Does anyone have the documentation on cp/m 2- 22 FJW->INFO-CPM A MENU Program for CP/M 3- 9 FJW->INFO-CPM Another typo 4- 32 FJW->MCTESQ How do you ... 5- 16 MCTESQ->INFO-CPM How do you ... 6- 12 MCTESQ->INFO-CPM Well I just started using CP/M today... 7- 18 Lauren@UCLA-SECURITY- Kick-off 8- 10 FJW->INFO-CPM Typo 9- 30 FJW->INFO-CPM STAT in 2.2 10- 118 FJW->INFO-CPM Kick-off 11- 10 LEAVITT@ISI->INFO-CPM CP/M WITH APPLE 12- 16 FJW->INFO-CPM CP/M Mailing List --Frank 10-Sep-80 03:53:00,11844;000000000000 Date: Wednesday, 10 September 1980 03:53-MDT From: BLUE at MIT-AI To: info-cpm at MIT-MC Frank -- following is a two part article that may be of some interest to some members of this list. It may be a little general for a few, but is fairly informative. Do with it as you see fit. --Bill CPM/TIPS Part 1 CP/M, A VIEW FROM INSIDE BY CARL ADLER Reprinted from NORTHWEST COMPUTER SOCIETY/July 1979 Although CP/M is not the ultimate in operating systems it is an extremely useful software devlopment tool which is implementable on a wide variety of 8080 and Z80 based computers. As a result it has become, by default i not by design, the standard of users of these microprocessors. CP/M's implementability lays mainly in the portability afforded to it through the use of the BIOS (Basic I/O System). This concept is a simple but very effective solution to the problem of hardware vari- ability inherent in microprocessor based computer systems. The S- 100 buss not withstanding there seem to be as many hardware config- urations as there are designers(as an example, my own computer has a 56 pin backplane and uses memory-mapped I/O). It is a surprising and welcome gesture for a software manufacturer to supply the exact procedures necessary to bring up its software. By the way of contrast, I know a very compulsive programmer who spent the better part of a month bringing up ISIS on a non-MDS hardware, whereas it took less than a week for this same programmer to bring up CP/M on the same hardware. The other major fctor in CP/M's success must be the configur- ability. How many microcomputer users start th 65K (wch ISIS requires to do anything useful)? With the ability to turn a 16K toy into a "real" computer, CP/M has ensured a very large following of devotees. As mentioned in thers manual, CP/M is divided into four logically distinct but interacting parts: BDOS (Basic Disk Operating System) BIOS (Basic Input/Output System) CCP (Console Command Processor) TPA (Transient Program Area) As there isn't a whole lot to say about the TPA other than that is where the transient programs are executed, and the users manual is very explicit on the use of the CCP, I will deal mainly with the BDOS and BIOS, Which I consider to be the heart of the system. THE BASIC DISK OPERATING SYSTEM (BDOS) The BDOS is the file manager of CP/M Though an application program can: .Open a file .Close a file .Search for th first and subsequent entries in the directory for a file .Erase a file from the directory .Read and Write logical rerds .Create entries in the diry .Rename entries in the directory as well as various support functions. These functions mainly add a level of abstraction to the disk hardware as implemented in the BIOS allowing the application program(mer) to deal with the stored data without having to know where it is physically located. The BDOS also acts as a conduit betweehe application program and the character I/O entry points in the BIOS as well as providing some macro-functions for string I/O to and from the console. Thus through the use of the BDOS, CP/M is able to transform a computer and its peripherals into a generalized sstem with no particular hardware characteristics machine language itself. (and through the use of one of the many "hi-level" languages which have been implemented to run under CP/M, it is possible to solve problems with out even knowing or caring what kind of CPU is running the show). To my way of thinking , this is a rather significant development in micro- computing. The BDOS functions are listed and explained quite throughly in the programmer's guide so I'll not bore the reader (and make myself type anyone than I have to) by reiterating them here. However I would like to address myself to a cuple of points which are associated with the BDOS. First, while monkeying around one day, I discovered that there are some strange locations at the beginning of the BDOS which can be (and most definitely are) used by transient programs even though they are supposedly secure inside the operating system. Here is an outline of these locations: ORG BDOS SERNUM: DS 6 ENTRY: JMP COMMAND DW BADIO DW SELERROR DW ROERRORMAP: LXI H,MAPTABLE ;POINT HL AT LOG TO PHYS MAPPING MVI B,0 ;SET BC TO LOICAL SECTOR (IN C) DAD B ;INDEX INTO TABLE MOV C,M ;CONVERT LOGICAL TO PHYSICAL SECTOR JMP SETSECTOR ;DO BIOS SET SECTOR FUNCTION NOP MAPTABLE: DB 1,7,13,19 DB 25,5,11,7 ;THIS TABLE MAPS LOGICAL ONTO DB 23,3,9,15 ; PHYSICAL DISK SECTORS DB 21,2,8,14 DB 20,26,6,12 DB 18,24,4,10 DB 16,22,,0 DB 0,0,0,0 ;THE NULLS ARE ADDRESS ALINGMENT CONFIG: DB SECPT ;SECTORS PER TRACK(26 ON IBM DISKS) DB LASTDIR ;NUMBERS OF LAST DIRECTORY ENTRY (63) DB RPB ;2**RPB=RECORDS PER BLOCK (3) DB LASTSEC ;LAST SECTOR IN BLOCK (7) DB LASTBLOCK ;LAST BLOCK ON THE DISK (242) DB DIRALLOC ;DIRECTORY ALLOCATION MASK (C0 HEX) DB DIRTACK ;TRACK THAT DIRECTORY BEGINS ON (2) The first 6 bytes of the BDOS contain the serial numbers which supposedly prevent copyright infringments. The next 3 contain the actual entry point to the BDOS command decoder. The next 9 bytes are the addresses of routines inside the BDOS which are executed when one of the three fatal errors occur. Following the error addresses is the routine which the BDOS uses to stagger its data on a track followed by the mapping table. After the mapping table are some constants which define the particular implementation of CP/M on specific size disks. The error address can be modified by an application program to recover somewhat more gracefully from a fatal error (I ran across this in a screen-oriented text editor which made possible to save the memory image of the program after an I/O error). The config- uration table data can be used (and is used by STAT in version 1.4) to find out what's going on with disk space. As far as I can tell it is not serendipitious that this infor- mation exists and is located where it is. It seems that the people at Digital Research left room for certain easy modifications and enhancements to CP/M. The second point I would like o address is the technique CP/M uses to do housekeeping on its files. All of the file management functions in the BDOS use the address of an FCB (file control block) as their parameter. Like the concept of the I/O byte the FCB is a rather elegant solution to the housekeeping problem in a file management system. It accomplishes two things for the operations system. First it "decentralizes" the process of maintaining "open files", and second, it gives application programs access to the same information about a file that the BDOS uses. These two factors together allow an application to get as close as it requires to the file management process. There are some problems with the FCB, as implemented. First there is the question of whether or not an application OUGHT to have access to housekeeping information as it is possible to louse things up pretty badly if things are not done correctly. This I think is a matter of taste. Since CP/M, as implemented, is a single-user system there isn't the problem of messing other people's files. The other problem is a bit more serious (rumor has it that Digital Research is dealing with . Since the largest number that an allocated block can have (see below) is 255(D) and with a block size of an even 2k, the maximum number of bytes of bytes of storage CP/M can address on one disk is approximately 510 kilobytes. This presents serious impediments (due to program standardization) to implementing the operating system on the larger disk systems becoming available. Be that as it may, within the scope of single (or perhaps double) density floppy disks, the FCB is in my opinion, a stroke of genius. Because an application, through the use of the FCB, has such flex- ibility it behooves the assembly language programmer to understand as best he or she can how to use it. The programmer's guide describes the format and I'll elaborate a bit on it. The FCB consists of seven fields of information each having a mnemonic associated with it. They are: FIELD FCB POSIONS ET 0 FN 1-8 FT 9-11 EX 12 NOT USED 13-14 ZC 15 DM 16-31 NR 32 The FN and FT fields are only logically distinct. The BDOS uses all eleven bytes as a fundamental unit of information when opening, closing, creating, erasing, searching and renaming files (The EX field is included during OPEN, CLOSE, CREATE and SEARCH opera- tions). It is the CCP and transient programs which make a distinction between file ame and file type. Since a file can be of any length up to the capacity of the disk and since a single FCB describes only 16k bytes of a file, there must be a way to link multiple sections of a file each described own by its. This is done via the EX field. The first extent of a file has an EX value of 0, the second a value of 1 and so on. The ET field is an interesting mixture of usefulness and ambi- guity. When the FCB is stored in the directory the ET filed may contain a 0, indicating that the entry is used, or, an E5(H) indi- cating that the entry has been deleted (or never used). However when the FCB is used as a parmeter for one of the file management functions, the ET field serves an entirely different purpose. If ET=0 then then the BDOS will assume that the command pertains to the currently selected disk. If the ET field is not zero then the BDOS assumes that it contains the disk number+1 to which the function pertains. In this case the BDOS will temporarily select disk number ET-1 and then clear ET to zero before proceeding with the requested function. When the file operation is complete, the BDOS will re- store ET to its original value. Thus, an application program need never concern itself with remembering or selecting specific disks as these values are retained throughout processing from the time that the CCP sets them up in the default FCBs. The RC field is essentially an "end of extent" pointer. It is "pushed" along by the NR field when writing and is used to limit the NR field during reading to prevent the reading of unwritten data. The DM field is an array of 16 bytes, each representing a logical block of data within the extent. The value of each of these bytes represents the physical area of disk space allocated to the logical block unless the value is 0, in which case the block has not been allocated any disk space. Together, the RC and DM fields form a "current" description of the locations on the dik used by the data contained with the extent. The NR field is used to specify which record, relative to the beginning of the extent, is to be read or written. The BDOS will automatically increment th number during read and write operations, making sequential file acess virtually automatic. 10-Sep-80 04:10:00,11916;000000000000 Date: Wednesday, 10 September 1980 04:10-MDT From: BLUE at MIT-AI To: info-cpm at MIT-MC CPM/TIPS Part 2 CP/M, A VIEW FROM INSIDE BY CARL ADLER Reprinted from NORTHWEST COMPUTER SOCIETY/July 1979 The BASI I/O SYSTEM (BIOS) This section of the system concerns itself with the hardwar dependent aspects of I/O. There are wo types: 1) Disk I/O, which is block oriented 2) Character I/O, which is byte oriented It is convenient to consider these two aspects seperately as they do not interact directly. Looking at the BIOS jump table (as described in the CP/M docu- mentation), the first two entries are paths to system initialization routines. The next six are entry points to the character I/O rou- tines and the rest are entry points to disk I/O and disk support routines. The section called "BIOS Entry Points" in the System Alteration Guide describes the function of each of these 15 entry points better than I could. However, what the guide does not do (as it is only a manual) is point out the importance of the I/O byte. I consider this to be deserving of special attention. Experience (mostly my own) has shown that until one makes concrete use of the I/O byte concept, it is difficult to appreciate the ele- gance of this technique. It does have its limits, but it is very simple and effective solution to CP/M's character I/O device standardization problems. I first ran across this concept on the MDS MOD-80 development system which did not have disk drives and used paper tape for its off-line storage. The Intel Monitor used a standard jump table which allowed programs to do character I/O without necessarily having to worry about the actual hardware devices. Perhaps you've seen it, but in case you haven't here it is. ORG MOINTOR JMP MAINLINE JMP CI ;COSOLE INPUT JMP RI ;READER INPUT JMP CO ;CONSOLE OUTPUT JMP PO ;PUNCH OUTPUT JMP LO ;LIST OUTPUT JMP CSTS ;RETURN CONSOLE STATUS JMP IOCHK ;RETURN I/O BYTE JMP IOSET ;CHANGE I/O BYTE (NEW VALUE IN C) As you can see thes basically the same that the BIOS jump table does. IOCHK, IOSET and MEMCHK art needed in the BIOS since the information returned by these rones are located in the zero page of CP/M's memory. As the alteration guide is not explicit on the bject of imple- menting an I/O byte, I'll outline in assembly language code the techniques I've found useful for a generized implation. But first notice that each of the six character I/O routines must decode out the path to the specific I/O device "currently assign- ed". The way this is done (in English) is as follows. The I/O byte contains four fields, each as consisting of low bits. Each field is associated with one of the fo"logical" I/O devices (Lnch, Reader and Console) and may take on the value of (in binary) 00, 01,10, or 11. Thus up to four different physical I/O devices may be associated with each of the four "logical" devices. For example, the logical device "List." By manipulating the value of these 2 bits (presumably) without affecting the rest of the byte) one may "assign" a specific hardware driver (and the device itself) to a specific hardware driver (and the device itself) to the list device. In PASCALese this is the decoder: VAR IOBYTE(4): PACD ARRAY OF (0..3) DO CASE IOBYTE(4) 0: TTYOUT; 1: LPTOUT; 2: CRTOUT; 3: USERLIST; END The alteration guide and documentation on PIP and STAT describe what these physical device might be. The command: STAT VAL: produces essentially a menu of the nominal phyiscal devices assignable in the CP/M system. Here is some software: IOBYTE EQU 3 ;LOCATION OF IOBYTE CMASK EQU 03H ;CONSOLE MASK RMASK EQU 0CH ;READER MASK PMASK EQU 30H ;PUNCH MASK LMASK EQU 0C0H ;LIST MASK RD2 EQU 08H ;READER DEVICE 2 MASK PD2 EQU 40H ;PUNCH DEVICE 2 MASK CONTIN: LDA IOBYTE ;GET IOBYTE ANI CMASK ;LOOK AT CONSOLE FIELD JZ TTYN ;CONSOLE 0: JPE UCIN1 ;CONSOLE 3: RAR ;CONSOLE1: JC KBDIN ;CONSOLE 1: JMP BACHIN ;CONSOLE 2 CONOUT: LDA IOBYTE ;GET IO BYTE ANI CMASK ;LOOK AT CONSOLE FIELD JZ TTYOUT ;CONSOLE 0: JPE UCOUT1 ;CONSOLE 3: RAR ;LOOK FOR CONSOLE 1 JC CRTOUT ;CONSOLE 1: JMP BACHOUT ;CONSOLE 2 CONSTAT: LDA IOBY UL1 ;LIST 3: JM LPTOUT ;LIST 2: JMP CRT ;LST 1; MISCELLANEOUS STUFF To conclude, there are some interesting tid-bits which the reader may (or may not for that matter) find useful. The SUBMIT processor in the CCP(Console Command Processor) uses a very interesting programming technique which I found worthwhile understanding. Recall that the transient program "SUBMIT" uses as its input a text file of CP/M commands and produces a file called $$$.SUB which the CCP will use as a command file. For example consider the following submit file: A:PIP B:PROG.ASM=B:PO.SRC,B:P1.SRC(CR)(LF) A:ASM PROG.BBB(CR)(LF) A:LOAD B:PROG(CR)(LF) A:PIP LST:=B:PROG,PRN(T8P50)(CR)(LF) The Submit program turns this file into a series of 128 byte records arranged such that the first line of the orginal file is the last record of the new file, the second line the second to the last record and so on. Each record has the following form: byte 1: length bytes 2-length+1: command string bytes length+2-128: undefined The above file would look like this when converted to $$$.SUB (the numbers in decimal and brackets are included here just for clarity): record 1: (28)A:PIP LST:=B:PROG,PRN(T8P50) record 2: (13)A:LOAD B:PROG record 3: (14)A:ASM PROG.BBB record 4: (33)A:PIP B:PROG.ASM=B:PO.SRC,B:P1.SRC Why, you ask, is $$$.SUB backwards? Well that's part of the trick. Remember that the RC field in the FCB is an end of extent pointer. If the $$$.SUB file is on the disk the CCP will open it and set the NR field of the FCB to RC-1 and read the file. What this does is read in the last record of the file (as determined by the RC field). After the read the CCP will decrement the RC field and close the file, which will cause the FCB and specifically the RC field command as if it had been typed in from the console. The next time around, the CCP will do the same thing except that the RC field is now pointing at the record whose number is one less than that of the previous operation. In other words, the RC field is used as an implicit record pointer. Very neat and it works too! Sometimes it is desirable to bypass the BDOS and communicated directly with certain BIOS functions. For example MICROSOFT's BASIC interpreter does not use the BDOS character I/O functions as it does its own line editing and the USCD Pascal system completely overlays the BDOS. There is a technique for accessing the BIOS that is general enough so as not to be consedered a kludge. An application can always find the page boundary on which the BIOS begins by examining the high order address byte of the warm boot entry point. Using that as the high order byte of the address the low order byte is set to an offset into that page as determined by: OFFSET=FUNCTION * 3 as each entry is three bytes. For example here is a short routine which causes data to be written to the list device: LOFF EQU 0FH ; BIOS+LOFF=LIST ENTRY LIST: PUSH H ; SAVE HL LHLD 1 ; GET ADDRESS OF WARM BOOT MVI L,LOFF ; SET LOW ORDER BYTE TO LIST OFFSET XTHL ; RESTORE HL, LIST ADDRESS ON STACK RET ; EXECUTE LIST ROUTINE IN BIOS This technique works as long as the BIOS begins on a page boundary. The more general technique would be: LOFF EQU 0FH-3 ; OFFSET FROM WARM BOOT ENTRY LIST: PUSH H ; SAVE HL LHLD 1 ; GET ADDRESS OF WARM BOOT PUSH D ; SAVE DE LXI D,LOFF DAD D ; GET TO LIST ENRY POINT POP D ; RESTORE DE XTHL ; RESTORE HL RET : EXECUTE LIST ROUTINE There is one more thing and then I'll quit. If you remember from above, I mentioned that while poking around inside a screen oriented text editor, I found that it modified the error address fields at the beginning of the BDOS. It also does another curious thing. In the editor there is a command to save the rest of the file, exit the editor and automatically process it with an entirely different program, such as an assembler or text formatter. There is an interesting technique here which could be generally useful. What happens is this: First, modify the address of the console input routine in the BIOS jump table to cause a routine inside the application program to supply data to the CCP. This is done as follows: LHLD 1 ; GET THE BIOS PAGE ADDRESS IN H MVI L,CI+1 ; HL IS THE ADDRESS OF THE ADDRESS ; OF CONSOLE INPUT ROUTINE MOV E,M ; GET THE DEVICE ADDRESS IN DE INX H MOV D,M XCHG SHLD SAVE ; SAVE IT FOR LATER LXI D,ALT ; DE IS ADDRESS OF ALTERNATE ROUTINE MOV M,D ; POKE JUMP ADDRESS ; IN BIOS JUMP TABLE DCX H MOV M,E JMP 0 ; AND RE-BOOT SAVE: DS 2 ; LOCATION USED TO SAVE ; CONSOLE INPUT DEVICE ADDRESS After doing this, everytime the CCP request a character from what it thinks is the console input device, it will be handed a character from inside the original application program. Just before handing the CCP a carriage return the application will restore the original address of the console input routine: LHLD SAVE ; GET ORIGINAL DEVICE ADDRESS XCHG ; PUT IN DE LHLD 1 ; GET ADDRESS OF ADDRESS FIELD OF ; CONSOLE INPUT ENTRY MVI L,CI+1 MOV M,D ; RESTORE ORIGINAL ADDRESS INX H MOV M,E ; ... AND CONTIN The routine that does the character handling is essentially this: LHLD POINTER ; GET ADDRESS OF NEXT CHARACT MOV A,M ; GET NEXT CHARACTER INX H ; ADVANCE POINTER SHLD POINTER ; SAVE POINTER CPI CR ; END OF DATA? RNZ ; IF NOT THEN JUST RETURN IT ; ELSE RESTORE CONSOLE ; INPUT ADDRESSES This works for two reasons: obviously the BIOS jump table can be considered data as well as code (hail to John Von Neumann) and since the original program will remain intact until the next program is actually loaded on top of it, the routine simulating the console will function normally. This technique suggests a viable method for chaining a series of programs together without having to specifically build a submit file for each chain. 14-Sep-80 00:07:00,700;000000000000 Date: Sunday, 14 September 1980 00:07-MDT From: Frank J. Wancho To: INFO-CPM at MIT-MC cc: FJW at MIT-MC Subject: CP/M Article (Updated) In the last pair of messages you received a copy of an article on the insides of CP/M. I have now placed online an updated version of that article (as of July 1, 1980), courtesy of Bruce Tompson (WB3ETS@AI), which was uploaded off of a disk file and re-edited. Due to its length, I will not retransmit it, but will send it to you by net mail upon specific request, or you can FTP the file yourself (MC:FJW;CPM DOC). Please keep in mind that the article was written before CP/M2, i.e., it applies to CP/M 1.4... --Frank