PROGRAMMING AND THE CMD HARD DRIVE by SYSOP JL Programmers' Workshop Conference July 19, 1990 This conference and paper outline some programming ideas, concepts and methods for using the CMD Hard Drive. CMD is a service mark of Creative Micro Designs, the manufacturer of the HD-20, HD-40 and HD-100 hard disks which are discussed in this paper. The ideas and methods presented in this paper are the work of the author and not CMD. Wherever ideas originated with CMD and are presented in this paper they will be noted as such. Much credit goes to CMD for the manual which provides the documentation necessary to use the CMD HD to it's full potential. This paper is not intended to be a substitute for that manual and anyone needing full documentation for the CMD HD should contact Creative Micro Designs for this information. There are three ways of viewing the CMD HD from a programming standpoint. 1. Those who do not have an HD but want their programs to be compatible. 2. Those who have HD's and are writing application programs other than disk utilities that take advantage of HD features. 3. Those who are writing disk utilities for the HD. This conference/paper primarily addresses viewpoint 1. During the conference I will address questions related to 2 and 3 to the best of my ability, and add appropriate ones to this conference paper. In general, the HD manual is very good, so those with viewpoints 2 and 3 can probably get what they need from the manual. Attempting to write applications that require the HD, or to write HD disk utilities, if you don't have a CMD HD is probably unwise. From a high level view, the CMD Hard Drive appears to be a multiple disk drive unit. A drive like the MSD-2 has 2 disk mechanisms and allows for addressing disk 0 or disk 1 in file names. As, for example, 0:fileondisk0 or 1:fileondisk1. The CMD HD (called just the HD in this paper) looks like up to 254 disks in a similar manner. The DRIVE specifier (0: or 1: on an MSD-2) can be 0: through 254: for the HD. Each drive specifier except 0: refers to a specific PARTITION on the HD. 0: for a drive specifier refers to the current active partition (and directory) set with the CHANGE PARTITION command, "CPn" where n is the partition number. Partitions on the HD can be EMULATION MODE partitions such as 1541, 1571, or 1581 emulation partitions. In these cases, the partition, once selected, will appear to be a disk drive of the emulated type. The HD is not exactly like the emulated drive type, but all appropriate commands will work and at least some disk drive programming, from a high level view, will work correctly. This can even extend to some programs which load into the disk drive if they use only high level internal commands and job queue commands in a manner usable on the emulated drive. The HD DOS memory map is different, however, so typically programs which execute in the disk drive will not work on an HD. The emulation mode partitions use the same BAM and directory structure as the emulated drive type. So directory routines, for example, written for an emulated drive type will generally work on an emulation mode partition of the appropriate type on the HD. Besides the emulation mode partitions mentioned, there are also NATIVE MODE partitions. Native partitions can take the full advantage of the HD features and capacity. This includes subdirectories, capacities per partition of up to 16 megabytes, unlimited number of files in the directory, etc. In order to have a program take advantage of any of the features of the HD it must first recognize that it is using an HD. The official method that CMD recommends for recognition of the HD is a memory read command to examine 6 bytes in the HD DOS at address $fea0. The bytes starting at this location will "always contain" the string "CMD HD" according to CMD. The following program fragment shows how to read these bytes: 100 open 1,dv,15: rem -- dv is the HD device number 110 s$="" 120 print#1,"m-r"+chr$(160)+chr$(254)+chr$(6): rem $fea0, 6 bytes 130 for i=1 to 6:get#1,x$:s$=s$+x$:next i 140 if s$="cmd hd" then Other methods, such as sending a disk command which currently only the CMD HD will recognize and checking disk status, run a risk of future obsolescence when the CMD RAMLink comes out. For example, the command to OPEN a partition directory, "$=p", which currently is only recognized by the HD, will perform the same function on a RAMLink according to CMD. Thus the RAMLink would appear to be a HD. Some HD functions, such as the clock, would not be accessible on this device, however. To find out what the current active partition is and what kind it is, use the "g-p" command. The following fragment applies... 100 open 15,dv,15:n$=chr$(0) 110 print#15,"g-p" 120 get#15,t$,x$,p$:t=asc(t$+n$):p=asc(p$+n$) The variable t will by the partition type, p will be the partition number. Some values for t and the indicated partition types are: 1 - Native mode 2 - 1541 emulation 3 - 1571 emulation 4 - 1581 emulation 5 - 1581 CP/M emulation Other values for the partition type indicate that it has not been created, it is a system partition, or it is not a CBM disk partition. In general, if your application program has been loaded and RUN from the HD, the user will have changed to the partition (and subdirectory, if applicable) where your program resides prior to running it. Thus any chained programs, binary files or data files will be accessible with standard OPEN and LOAD commands such as OPEN lf,dv,sa,"filename" or "0:filename". Or LOAD"0:progfile",dv,1. It is possible, however, that your program will have been run with a command like... LOAD"112//games/card/:yourprogram",10 which would have gotten your program from the HD device#10 in partition number 112 and subdirectory games/card. In this case, reading data files from the current partition and subdirectory may not work. There are several alternatives to making your program work in this case. One, use MODLINK (for example) to combine your ML and binary data with your program so it is all loaded into computer memory with the LOAD command that loads your program. Second, you can check for the files you need by using an OPEN command, then checking disk status for a 'file not found' status. If the files cannot be found in the current partition and directory, then you can ask the user to input the appropriate drive info to provide a path to your files. A third method is to always provide a menu selection or option where the program user can send disk commands, so he can send the appropriate CP, CD or / commands to set up the path you need. A fourth method is to dynamically create a boot program that knows a particular users configuration. The boot program would be created by an INSTALL program that you would write and distribute with your application. If you take the approach of asking for path info, you may need to ask for: UNIT (Unit 8, 9, 10, etc) to be used for the device parameter; PARTITION, to be used as the drive number parameter; and PATH to be used as a prefix to your file names in OPEN or LOAD commands. To access your files directly would then take a command like... OPEN lf,dv,sa,"pn//path/:yourfile" lf = logical file number dv = device sa = secondary address pn = partition number path = the subdirectory path in partition pn where 'yourfile' is at. You could also make this the current directory and partition with the following commands sent to the command channel... OPEN 15,dv,15 PRINT#15,"cP"+chr$(pn) PRINT#15,"CD"+PA$ The "cP" is one of two forms of the change partition command. "cp#" is used where the entire command is all ascii with no imbedded spaces... as in "cp112". The "c" form is more convenient in programs since the partition number is a single ASCII character that you can use the CHR$() function to make. PA$ would have the form "//dirname1/dirname2/...dirnameN" depending on how many subdirectories deep the nesting is. An additional method that you might use for providing a more convenient operating program is to use an INSTALL program to set up a boot program. An install program creates a modified boot program on disk. It would ask for the device number, partition and path where the program is to be installed. It would then select that partition and path on the device indicated and write a boot program there. The install program is run once when the user first starts using your application. After that the modified "boot" program can be run from any partition and it will set the partition and directory, set up any required variables or memory configuration, then load your main program. This approach will be especially useful if future versions of the HD DOS add a "path" command that allows the user to set up a search path for programs to be loaded. For some programs it is desirable to have program files in one place and data files in another. Database programs, word processors and assemblers or compilers, for example. There are two ways to approach this on the HD. One is to have your program and needed other program and data files in the current partition and directory and access user data via a path. The second is the other way around. The normal situation is that when your program is started, the current default path will give you access to your program files. In this case you would want the user to tell your program what the path is to his data files. Bear in mind that he might want to work on a file in one path and later to work on a file in a different path. So you will want a top level menu that allows selecting a data file path such that it can be changed. A general purpose application program would request the drive where the data is located. That drive would then be checked to see if it exists and what type of drive it is. If the drive is a HD (or RAMLink?) then the appropriate partition and path information would be requested. If it is a floppy drive then your program would request that the user put the data disk in the drive. Miscellaneous things, in no particular order... READING DIRECTORIES: I recommend for ALL drive types, including the CMD HD, that you read a directory by opening a directory load file and reading it like a BASIC program file. Many directory routines rely on the directory starting at a particular track and sector and using the U1 (block read) command to get each track and sector. This would not work on native mode directories or subdirectories on the HD and it does not work on RAMDOS disks. The following program statement can be used to open a directory on ANY disk drive: 100 open 1,dv,0,"$0" For the directory file on an HD there are several different forms it can take. "$" or "$0" will read the full directory of all files, subdirectories and/or sub-partitions on the current partition and subdirectory. "$=p" will give a directory of partitions on the HD. The normal 'file type' field of the directory will give the type of partition. A partial list of these is... SYS - system NAT - native 41 - 1541 emulation 71 - 1571 emulation 81 - 1581 emulation 81C - 1581 CP/M emulation "$*=b" will give the directory of subdirectories in the current partition and directory if the partition is a native partition. The files will have a file type field of DIR. "$*=c" will give a directory of all sub-partitions in the current directory of a 1581 emulation partition (just like a real 1581 disk drive does). The listed files will have a file type of CBM. You can also use pattern matching in the same manner as for a 1581 disk drive. That is, "$0:*.bud" will give a listing of all files with a ending of .bud. Particularly useful for finding all those .mus files on a native partition with a thousand or so files in it. DISK STATUS RESPONSE: In using disk commands, the only thing about status response that is special to the HD is in response to a "CPn" command. This returns a disk status 2, "partition selected" followed by the decimal value of the partition number. This is similar to the status returned by a 1581 in response to a "/partition-name" command. "cp5" or "cP"+chr$(5) would return the status "02, partition selected, 05, 00" followed by a carriage return. HD CLOCK FEATURES: A useful addition to the CMD HD is date and time stamping of all files. You can have a directory list include a short form of the date and time the file was created with "$=t" or "$=t:*" where * is the pattern matching string you want to use. Such as, "$=t:cmd*.128=p" to get a directory of all C128 CMD utility programs in the current directory or "$=t:*.mus" for a listing of all SID music files with the creation date. Date and time stamping by HD DOS uses the same directory format as GEOS does for date and time stamping. Thus GEOS created directories and CMD HD created directories are compatible for all emulation partitions as well as native partitions. You can also read and use the HD Disk Drive clock and use the date and time information in your program. For example, to provide a date and time printout line at the top of a printed page. I did that in the program "hd tree.128v1.4" FILES: A 1541 or 1571 disk drive is limited to a maximum of 3 files open at one time, or one REL file plus one other PRG or SEQ file. The 1581 disk drive is limited to 4 files, or 3 files if one of them is a REL file. These limitations do not exist on the HD. The C64 and C128 Kernal limit files open to be a maximum of 10, and the HD supports at least that many files, of any type. About RELative files... According to CMD, all REL file bugs that exist in 1541 and 1571 drives are corrected in the HD DOS. REL files are fully functional without special care being needed to assure that records written to the drive get dumped to disk rather then left in a buffer to get clobbered. This means that the extra position command after a REL record write is not needed. They also recommend, however, that a general purpose program should retain the extra position command for backwards compatibility to other drives. The HD supports CBM's 1581 super-side- sector format for REL files in all partitions. REL files created in 1541 or 1571 emulation partitions will be format compatible with the emulated drive, however ones created on native partitions or 1581 emulation partitions will not have the 720 disk block max size limit. These super side sector REL files can be copied to a '41 or '71 emulation partition and will be fully functional including the super side sector support once they are there. In summary, the basic things you need to do in a program in order to have it at least usable on a HD are the same things you need to do to have it usable on any other generic drive. Do not expect that things are kept at certain places on the disk or in drive memory; use directory load file formats to read directory info instead of block read, etc; allow drive numbers other than 0: in file names; provide a means for the program user to send disk commands; make your program load as a single unit rather than loading in separate modules if you can; or, if you cannot do it without loading separate modules, then consider using an "install" program to create a user customizable boot program that handles system configuration duties. This is intended as a general outline. I would encourage you to use it as a guideline since every program is different so there is no fixed set of rules that apply to everyone. If you do not have a HD and write any application which is designed to be supportive of the HD then I would encourage you to upload it to the Q-Link Programmers' Workshop "Beta Test Center" for testing with an HD. This could well be the up-and-coming new tool that will put a lot of new life in those C64 and C128 application programs. Learn to work with it and your programs will stay healthy.