PROCEDURE MakeDesc (* NOTE: Assumes any legit device descriptor module starting with 't' is for (* the initial testing/setup only! (* Version 0.2 - T0S (# sectors on track 0) should be set to 0 for any drive (* that is using CHS mode. It should be set to the number of "extra" sectors (* that are available in LBA mode above and beyond the result of CYL*HEAD* (* SECTORS when using a drive with LBA mode. This will NOT be used by CCIDE (* itself, but the new format command. The only exception to this rule is (* when one mixes CHS & LBA modes on the same physical drive (usually to get (* around bad sectors on a drive), in which case you MAY have to 'pad' the (* CHS partition of the drive with extra sectors to resync up with the 32MB (* chunks that LBA mode uses. (* MAKEDESC should also be changed to handle doing all the partitions for (* a drive at once, so that it can keep track of overlapping, etc. (* It should also allow the option of using the new GETSTAT call for getting (* the drive info. (* Also have to add support for ForceCHS bit in DD.DNS. (* Version 0.1 - changed do DD.DRV is the partitioned drive #, and least (* sig bit of DD.DNS is the physical IDE drive #) (* The driver could/should be updated later to use the unused DMODE stuff (* later (8K caching, for example) (* Later, we should add in commands that Identify the drive, and allow the (* user to accept the drives default parms for setting a descriptor up. Only (* time this would be unacceptable is with a drive >4GB, where one would (* need several descriptors, each with different OFS settings to handle more (* than 4 GB. Or, if drive >128MB, and user wants only 1 sector/cluster (for (* compatibility with EZGEN & other utilities). (* Please note, that in CHS mode, there are some limitations to the (* translation software in the CCIDE driver itself. It has the following (* limits on the 6809: (* Max. cylinders: 4096 (* Max. heads: 16 (IDE limitation) (* Max. PC sectors/track: 255? (* The 6309 version, when done, should bump up these limitations to: (* Max cylinders: 32767 (* Max heads: 16 (* Max sectors: 127 if DIVD used, 32767 if DIVQ used (haven't decided yet) TYPE drinf1=config,cyl,res,heads,unfbtk,unfbsc,scptk,res2(3):INTEGER ; serial:STRING[20]; buftyp,bufsiz,ecc:INTEGER; firmware:STRING[8 ]; model:STRING[40]; mult,dword,cap,res3:INTEGER TYPE drinf2=piotime,dmatime,valid,curcyl,curhead,cursptk,curcap( 2),multsec,lbasec(2),singdmamode,doubdmamode,advpiomode,dmatime,mandmatime ,piotimenflow,piotimeflow,res4(2):INTEGER TYPE drinf3=timeovl,timesvc,majrev,minrev,res5(53),vend(32),res6 (96):INTEGER TYPE sub=d1:drinf1; d2:drinf2; d3:drinf3 DIM driveinfo:sub TYPE registers=cc,a,b,dp:BYTE; x,y,u:INTEGER DIM regs:registers TYPE direntry=name:STRING[29]; ptr(3):BYTE DIM dirent:direntry DIM pdopt(32):BYTE DIM pathname:STRING[80] DIM curphys,maxsel,foundphys,foundlog,errnum,c,counter,tempnum,maximumdrive :INTEGER DIM address,tempmod(56),outfile,infile,headerparity:BYTE DIM physused(2):BOOLEAN DIM temp:STRING[32] DIM outfilename:STRING[29] DIM shellline:STRING[119] DIM lbaallowed(2),dummy:STRING[2] DIM dummydrive:STRING[4] DIM usedsectors,cylsize,cylsleft,maxsect(2),tempbig,tempbig2,chssectors (2),lbasectors(2),totalcyl(2),totalhead(2),totalsect(2):REAL DIM partitionstart,lastparttype,totalpartitions,currentpart:INTEGER DIM checkdsc:STRING[3] DIM desccyl,deschead,descsct,desct0s:INTEGER DIM ulineon,ulineoff:STRING[2] (* Change following IF you modify the driver CCIDE to handle more or less (* logical drives) maximumdrive=11 TYPE moduledata=offset(56):BYTE DIM moddata(11):moduledata DIM usedflag(11):BOOLEAN DIM lba(11):STRING[2] DIM olddescfile(11):direntry (* End of block that has to change if you change the # of logical drives in (* the driver. ulineon=CHR$($1F)+CHR$($22) ulineoff=CHR$($1F)+CHR$($23) checkdsc=".d"+CHR$($E4) FOR counter=1 TO maximumdrive usedflag(counter)=FALSE lba(counter)="" NEXT counter FOR counter=1 TO 2 physused(counter)=FALSE chssectors(counter)=.0 lbasectors(counter)=.0 lbaallowed(counter)="" NEXT counter PRINT CHR$(12); "MAKEDESC - CCIDE Device descriptor builder Version 0.2" PRINT "Copyright (C) 1999 by L. Curtis Boyle, but feel free to distribute." PRINT "It is HIGHLY recommended you run this in an 80 column window." PRINT "Please note that you will be doing one physical drive at a time." PRINT "At which address is the IDE card you are setting up a drive(s) on:" PRINT "<1> $FF50" PRINT "<2> $FF70" c=0 WHILE c<1 OR c>2 DO INPUT "Select <1-2>:",c ENDWHILE IF c=1 THEN address=$50 ELSE address=$70 ENDIF 5 PRINT "Please type in the COMPLETE path to your modules directory that will contain" PRINT "your hard drive device descriptors: (Ex. '/dd/modules'):" INPUT "",pathname ON ERROR GOTO 10 PRINT "Checking for existing drive descriptors...assuming *.dd" 7 OPEN #outfile,pathname:READ+DIR ON ERROR GOTO 20 10 errnum=ERR ON ERROR IF errnum=216 OR errnum=221 THEN PRINT "Could not fine the path "; pathname; "!" PRINT "ERROR "; errnum GOTO 5 ELSE ERROR errnum END ENDIF 20 foundlog=0 foundphys=0 WHILE NOT(EOF(#outfile)) DO GET #outfile,dirent IF LEFT$(dirent.name,1)<>CHR$(0) AND SUBSTR(checkdsc,dirent.name )>1 AND LEFT$(dirent.name,1)<>"t" THEN temp=dirent.name FOR c=0 TO LEN(temp)-1 EXITIF PEEK(ADDR(temp)+c)>$80 THEN POKE ADDR(temp)+c,PEEK(ADDR(temp)+c)-$80 ENDEXIT NEXT c temp=LEFT$(temp,c+1) OPEN #infile,pathname+"/"+temp:READ regs.a=infile regs.b=2 RUN Syscall($8D,regs) IF LAND(regs.cc,1)=1 THEN ERROR regs.b ENDIF IF regs.x=0 AND regs.u=56 THEN GET #infile,tempmod IF tempmod(17)=address AND tempmod(46)=$43 AND tempmod(47)=$43 AND tempmod(48)=$49 AND tempmod(49)=$44 AND tempmod(50)=$C5 THEN PRINT "Found "; LEFT$(dirent.name,SUBSTR(checkdsc,dirent.name)-1 ) tempnum=tempmod(20) IF tempnum>maximumdrive-1 THEN PRINT "ERROR: found a logical drive # of "; tempnum; " in "; dirent.name ; " - current MAKEDESC maximum is "; maximumdrive-1 END ENDIF olddescfile(tempnum+1)=dirent physused(LAND(tempmod(23),1)+1)=TRUE (* PLEASE NOTE THAT THE FOLLOWING CHECK _MAY_ NOT BE CORRECT IF THE DEVICE (* DESCRIPTOR WAS MADE BEFORE THIS VERSION OF MAKEDESC.BAS WAS WRITTEN. THIS (* VERSION OF MAKEDESC.BAS DEPENDS ON THE 'CHS OVERRIDE' BIT TO BE SET ON (* _ALL_ CHS DRIVES, EVEN IF THE DRIVE CAN NOT RUN IN ANY MODE _BUT_ CHS! IF LAND(tempmod(23),2)<>0 THEN lba(tempnum+1)="N" ELSE lba(tempnum+1)="Y" ENDIF IF usedflag(tempnum+1)=TRUE THEN PRINT "ERROR: Found a 2nd logical drive # of "; tempnum; ". Please rename one of descriptors" PRINT " so that it does not have the extension of '.dd', and run MAKEDESC again." END ELSE usedflag(tempnum+1)=TRUE foundlog=foundlog+1 moddata(foundlog)=tempmod ENDIF ENDIF ENDIF ENDIF ENDWHILE CLOSE #outfile PRINT "Found "; foundlog; " IDE drive descriptors for your controller address (not including" PRINT "the 't*.dd' test drives)" GOSUB 5000 curphys=0 IF foundphys=1 THEN PRINT "Are you:" PRINT "<1> Adding a 2nd physical drive, or" PRINT "<2> Replacing your first physical drive" maxsel=2 GOSUB 2000 FOR counter=1 TO maximumdrive EXITIF usedflag(counter)=TRUE THEN curphys=LAND(moddata(counter).offset(23),1) ENDEXIT NEXT counter IF c=2 THEN tempnum=0 GOSUB 6000 GOSUB 3000 curphys=curphys+1 ELSE curphys=1-curphys+1 ENDIF ELSE IF foundphys=2 THEN PRINT "Are you:" PRINT "<1> Replacing just one physical drive, or" PRINT "<2> Replacing both drives" maxsel=2 GOSUB 2000 IF c=2 THEN GOSUB 5990 GOSUB 3000 curphys=0 ELSE PRINT "Are you replacing:" PRINT "<1> the Master drive (drive 0), or" PRINT "<2> the Slave drive (drive 1)" GOSUB 2000 curphys=c c=c-1 tempnum=c GOSUB 6000 FOR counter=1 TO maximumdrive IF usedflag(counter)=TRUE AND LAND(moddata(counter).offset(23),1 )=c THEN usedflag(counter)=FALSE foundlog=foundlog-1 ENDIF NEXT counter foundphys=foundphys-1 PRINT "You will have "; foundlog; " logical drives left from your other drive, leaving you" PRINT "with room for "; maximumdrive-foundlog; " logical drives on your new drive." ENDIF ELSE GOSUB 3000 ENDIF ENDIF (* Set up tempmod for default settings GOSUB 4000 (* Set address of controller tempmod(17)=address dummy="" REPEAT PRINT "Do you have 'dummy' drive descriptors, and the CCIDE driver, in memory at" PRINT " this time for the drive you are adding or changing? (y,n):" ; INPUT "",dummy IF dummy="n" THEN dummy="N" ELSE IF dummy="y" THEN dummy="Y" ENDIF ENDIF UNTIL dummy="Y" OR dummy="N" IF dummy="N" THEN (* Prompt for drive limits and stuff here PRINT "If, for any of the following questions, you do not know the answer, press" PRINT ", and then either run DETECT_IDE to get the information, or reboot" PRINT "with a bootfile that contains CCIDE and the proper 'dummy' device descriptors" PRINT "(t0 and/or t1) for the drives you have hooked up to your system." PRINT "If you are going to use the DETECT_IDE method, make sure you have the" PRINT "following information written down:" PRINT " 1- Does the drive support LBA mode" PRINT " 2- What is the # of cylinders on the drive" PRINT " 3- What is the # of heads on the drive" PRINT " 4- What is the # of sectors/track on the drive" PRINT " 5- If the drive supports LBA mode, how many sectors are available in LBA mode" c=0 GOSUB 9000 INPUT "Does your drive support LBA mode (y,N):",lbaallowed(curphys ) IF lbaallowed(curphys)="Y" OR lbaallowed(curphys)="y" THEN lbaallowed(curphys)="Y" PRINT "How many 512 byte sectors (use decimal!) does your drive support in LBA mode:" INPUT "",lbasectors(curphys) ELSE lbaallowed(curphys)="N" lbasectors(curphys)=.0 ENDIF GOSUB 1000 ELSE INPUT "Name of 'dummy' drive descriptor you want to access the physical drive for:" ,dummydrive IF LEFT$(dummydrive,1)<>"/" THEN dummydrive="/"+dummydrive ENDIF OPEN #infile,dummydrive+"@":READ (* 1st, get PD.OPT stuff so we can get physical drive # regs.a=infile regs.b=0 regs.x=ADDR(pdopt(1)) RUN Syscall($8D,regs) c=LAND(pdopt(5),1) physused(c+1)=TRUE curphys=c+1 tempmod(23)=c (* Now, get Identify drive info regs.a=infile regs.x=ADDR(driveinfo) regs.b=$8F regs.y=0 RUN Syscall($8D,regs) IF LAND(regs.cc,1)<>0 THEN PRINT "Error getting info for SS.DrvInf" ERROR regs.b ENDIF IF regs.b>1 THEN PRINT "ERROR: Does not appear to be an ATA or ATAPI drive!" END ENDIF PRINT "Have physical information from drive itself." (* Current driver does not support ATAPI yet - and will need other calls even (* when it does IF regs.b=1 THEN PRINT "Sorry, can not configure an ATAPI drive at this time." END ENDIF foundphys=foundphys+1 GOTO 100 ENDIF (* No test descriptors - get drive # by hand - default to next available drive (* if one is already used and being kept IF foundphys<>1 THEN GOSUB 9000 ENDIF (* Entry point if GetStat worked, and we have physical drive info 100 IF dummy="Y" THEN totalcyl(curphys)=FLOAT(driveinfo.d1.cyl) totalhead(curphys)=FLOAT(driveinfo.d1.heads) totalsect(curphys)=FLOAT(driveinfo.d1.scptk) chssectors(curphys)=totalcyl(curphys)*totalhead(curphys)*totalsect (curphys) IF LAND(driveinfo.d1.cap,$0200)<>0 THEN lbaallowed(curphys)="Y" tempbig=PEEK(ADDR(driveinfo.d2.lbasec(1)))*16777216.+PEEK(ADDR(driveinfo.d2.lbasec (1))+1)*65536. lbasectors(curphys)=tempbig+PEEK(ADDR(driveinfo.d2.lbasec(2)))*256. +PEEK(ADDR(driveinfo.d2.lbasec(2))+1) ELSE lbaallowed(curphys)="N" lbasectors(curphys)=.0 ENDIF ENDIF PRINT PRINT "Current drive configuration for physical drive #"; curphys -1; ":" PRINT "Cylinders :"; totalcyl(curphys) PRINT "Heads :"; totalhead(curphys) PRINT "512 byte sectors/track :"; totalsect(curphys) PRINT "LBA mode Supported :"; lbaallowed(curphys) IF lbaallowed(curphys)="Y" THEN PRINT "512 byte sectors in LBA mode:"; lbasectors(curphys) ENDIF PRINT PRINT "Are these:" PRINT "<1> Correct as they are, or" PRINT "<2> Need corrections (incorrect translation from drive, etc.)" c=0 REPEAT INPUT "Select <1-2>:",c UNTIL c>0 AND c<3 IF c=2 THEN GOSUB 1000 ENDIF PRINT "Your drive has a total of "; chssectors(curphys); " 512 byte sectors available in CHS mode." IF lbaallowed(curphys)="Y" THEN PRINT "Your drive has a total of "; lbasectors(curphys); " 512 byte sectors available in LBA mode." ENDIF chssectors(curphys)=chssectors(curphys)*2. lbasectors(curphys)=lbasectors(curphys)*2. PRINT "("; chssectors(curphys); " 256 byte OS9 sectors in CHS mode)" PRINT "("; lbasectors(curphys); " 256 byte OS9 sectors in LBA mode)" IF lbasectors(curphys)>chssectors(curphys) THEN maxsect(curphys)=lbasectors(curphys) ELSE maxsect(curphys)=chssectors(curphys) ENDIF cylsize=totalhead(curphys)*totalsect(curphys)*2. totalsect(curphys)=totalsect(curphys)*2. IF maxsect(curphys)>524280. THEN PRINT "Your drive is greater than 128MB, and will need clustering and/or partitioning" PRINT "done to access all of it." IF maxsect(curphys)>16777216. THEN PRINT "Your drive is also greater than 4 GB, which you means you will HAVE to part-" PRINT "ition it to access all of it." ENDIF ELSE PRINT "Your drive is <= 128 MB - partitioning or clustering is not recommended (un-" PRINT "less you really want to, or have to avoid a bad start track on the drive)" ENDIF (* Prompt for # of partitions (and give recommended settings) GOSUB 7000 PRINT "You currently have enough room for "; maximumdrive-foundlog ; " logical drives left." PRINT "If you are adding 2 physical drives, make sure any partitioning you do leaves" PRINT "you with enough logical drives to cover them both!" maxsel=maximumdrive-foundlog 150 PRINT "How many partitions (logical drives) are you making on physical drive #" ; curphys-1 PRINT "(If you are just redoing a descriptor for a single partition, just pick '1')" GOSUB 2000 totalpartitions=c currentpart=1 IF totalpartitions*16777216."Y" AND temp<>"y" THEN 150 ENDIF lastparttype=0 (* Main partitioning loop WHILE currentpart<=totalpartitions DO PRINT "Creating partition #"; currentpart; " of "; totalpartitions ; ", "; maxsect(curphys); " OS9 sectors left to allocate." (* Automatically assign logical drive # by next available drive, but have a (* prompt to override in case user is changing an existing descriptor FOR c=1 TO maximumdrive EXITIF usedflag(c)=FALSE THEN ENDEXIT NEXT c IF c=maximumdrive+1 THEN PRINT "ERROR: ALL "; maximumdrive; " LOGICAL DRIVE #'S ARE USED! YOU NEED TO EITHER" PRINT "REDUCE YOUR NUMBER OF LOGICAL DRIVES, OR MODIFY THE DRIVER & MAKEDESC TO" PRINT "HANDLE MORE LOGICAL DRIVES!" END ENDIF 200 PRINT c-1; " is the next available logical drive number." PRINT "Hit for next available, or pick a logical drive # from 0-" ; maximumdrive-1; INPUT ":",temp IF temp="" THEN tempmod(20)=c-1 ELSE tempmod(20)=VAL(temp) ENDIF IF tempmod(20)<0 OR tempmod(20)>maximumdrive-1 THEN 200 PRINT "Logical drive #"; tempmod(20); " selected." IF lbaallowed(curphys)="Y" THEN INPUT "Your drive supports LBA mode. Do you wish to make this partition LBA (Y,n):" ,temp IF temp<>"N" AND temp<>"n" THEN tempmod(23)=LAND(tempmod(23),$FD) PRINT "LBA mode selected." GOTO 250 ENDIF ENDIF tempmod(23)=LOR(tempmod(23),2) PRINT "CHS mode selected." 250 IF maxsect(curphys)<524280. THEN PRINT "You can fit the entire remainder of the drive into 1 partition with a cluster" PRINT "size of 1." ELSE IF maxsect(curphys)<16777216. THEN PRINT "You can fit the entire remainder of the drive into 1 partition with a minimum" PRINT "cluster size of "; tempbig=maxsect(curphys)/524280. tempbig2=tempbig GOSUB 8000 ELSE PRINT "You can fit a maximum of 4GB into 1 partition with a cluster size of 64." ENDIF ENDIF IF lastparttype=0 THEN PRINT "Doing 1st partition for drive" tempbig=.0 temp="" ELSE PRINT "Last logical drive (# "; lastparttype-1; ") was a "; tempnum=moddata(lastparttype).offset(23) IF LAND(tempnum,2)<>0 THEN temp="C" PRINT "CHS"; ELSE temp="L" PRINT "LBA"; ENDIF PRINT " mode partition, and ended "; tempbig=moddata(lastparttype).offset(24)*256.+moddata(lastparttype ).offset(25) tempbig=tempbig*(moddata(lastparttype).offset(28)*256.+moddata(lastparttype ).offset(29)) tempbig=tempbig*FLOAT(moddata(lastparttype).offset(26)) tempbig=tempbig+FLOAT(moddata(lastparttype).offset(30)*256.+moddata (lastparttype).offset(31)) IF temp="L" THEN tempbig=tempbig+(moddata(lastparttype).offset(39)*256.+moddata(lastparttype ).offset(40))*131072. ELSE tempbig=tempbig+(moddata(lastparttype).offset(39)*256.+moddata(lastparttype ).offset(40))*cylsize ENDIF PRINT tempbig PRINT "OS9 sectors ("; tempbig/4.; " KB) into the drive." ENDIF IF lbaallowed(curphys)="Y" AND LAND(tempmod(23),2)<>0 THEN PRINT "It is STRONGLY recommended that you make any CHS partitions on an LBA drive an" PRINT "even multiple of 32 MB in size, or you will waste the extra space between" PRINT "partitions (unless, of course, you are on the last partition). It is also" PRINT "STRONGLY recommended that you only use CHS partitions on an LBA mode drive to" PRINT "avoid bad tracks, as CHS mode is up to 10% slower then LBA mode." IF MOD(tempbig,131072.)<>.0 THEN PRINT "WARNING: Last partition did not end on an even 32 MB boundary!" ENDIF ENDIF (* Now, make a default partition start based on CURRENT mode, and where last (* partition left off. Do NOT allow user to point the partition to BEFORE the (* end of the previous drive! IF lastparttype=0 THEN partitionstart=0 ELSE (* Calculate recommended partition start, based on mode IF LAND(tempmod(23),2)=0 THEN (* LBA mode - HAS to start on 32 MB (131072 OS9 sectors) boundary tempbig2=tempbig/131072. IF MOD(tempbig,131072.)<>.0 THEN tempbig2=tempbig2+1. ENDIF partitionstart=tempbig2 PRINT "Recommended partition start is:"; partitionstart PRINT " (This is the number of 32 MB 'chunks' into the drive)" PRINT "(Starting "; partitionstart*32.; " MB into the drive)." ELSE (* CHS mode - HAS to start on 'cylsize' sector boundary (cylinder boundary) tempbig2=tempbig/cylsize IF MOD(tempbig,cylsize)<>.0 THEN tempbig2=INT(tempbig2)+1. PRINT "Last partition did not end on an even cylinder...you will lose " ; tempbig2*cylsize-tempbig; " sectors" ENDIF partitionstart=tempbig2 PRINT "Recommended partition start is cylinder "; partitionstart ; "." ENDIF 300 INPUT "Hit to accept partition start, or type in a new one:" ,dummy IF dummy<>"" THEN tempnum=VAL(dummy) IF tempnum131072. AND lbaallowed(curphys)="Y" THEN IF currentpart16777216. THEN maxsel=16777216./cylsize PRINT "Remaining space >4GB, # of cylinders to be allocated has to be <=" ; maxsel ELSE maxsel=INT(cylsleft) ENDIF IF LAND(tempmod(23),2)<>0 THEN PRINT "Note that CHS mode will only allow a maximum of 4096 cylinders at this time." IF cylsleft>4096 THEN maxsel=4096 ENDIF ENDIF 350 PRINT "Number of cylinders to allocate to this partition "; GOSUB 2000 IF c*cylsize>16777216. THEN PRINT "That is over 4 GB! You will have to select a smaller size!" GOTO 350 ENDIF IF maxsect(curphys)-c*cylsize<.0 THEN PRINT "That is bigger than the amount of room left on the drive! You will have to" PRINT "select a smaller size!" GOTO 350 ENDIF PRINT "This partition will be "; c*cylsize/4.; " KB ("; c*cylsize /4096.; "MB)." IF currentpart<>totalpartitions THEN PRINT "If you are mixing modes, then this should be on a multiple of 32 MB boundary," PRINT "unless you are skipping bad parts of the drive. (Remember, you can add 'extra'" PRINT "later!)" ENDIF INPUT "Is this acceptable (Y,n):",dummy IF dummy="N" OR dummy="n" THEN 350 desccyl=c IF desccyl*cylsize>524280. THEN PRINT "Don't forget that you will have to format this partition with a cluster size" PRINT "of at least "; tempbig2=desccyl*cylsize/524280. GOSUB 8000 ENDIF maxsect(curphys)=maxsect(curphys)-desccyl*cylsize IF MOD(desccyl*cylsize,131072.)<>.0 AND maxsect(curphys)>.0 AND currentpart <>totalpartitions THEN PRINT "If you want this partition to end on an even 32 MB boundary, you will have to" PRINT "pad "; (INT(desccyl*cylsize/131072.)+1.)*131072.-desccyl* cylsize; " extra sectors." ELSE PRINT "This partition will need NO extra sectors to end on an even 32 MB boundary" ENDIF IF currentpart<>totalpartitions THEN PRINT "If you want this partition to end on an even cylinder (CHS mode boundary)," PRINT "then you will have to pad "; IF LAND(tempmod(23),2)=0 THEN IF MOD(partitionstart*131072.,cylsize)=.0 THEN PRINT "0 sectors, or even multiples of "; cylsize; " sectors." ELSE PRINT (INT(partitionstart*131072./cylsize)+1.)*cylsize-partitionstart *131072.; " sectors" ENDIF ELSE PRINT "0 sectors, or even multiples of "; cylsize; " sectors." ENDIF ELSE PRINT "ON LAST PARTITION - EVEN CYLINDER AND/OR 32 MB 'CHUNK' IS _NOT_ NECESSARY!" PRINT maxsect(curphys); " sectors currently left over." IF maxsect(curphys)>65535. THEN PRINT "Warning-you are on your last partition, but you need more than 65535 extra" PRINT "sectors to finish using all of your drive. You may want to redo this drive" PRINT "with either more partitions, or larger clustering." ELSE PRINT "You will need to assign "; maxsect(curphys); " extra sectors to finish using up the" PRINT "current drive." ENDIF ENDIF 400 INPUT "Would you like to pad the drive size with extra sectors (y,n):" ,dummy IF dummy<>"Y" AND dummy<>"y" AND dummy<>"N" AND dummy<>"n" THEN 400 tempbig2=-1. IF dummy="Y" OR dummy="y" THEN WHILE tempbig2<.0 OR tempbig2>65535. DO INPUT "How many extra sectors do you want to add (1-65535):",tempbig2 IF tempbig2+desccyl*cylsize>16777216. THEN PRINT "That makes it bigger than OS-9 can handle! Try a smaller number!" tempbig2=-1. ENDIF IF tempbig2>maxsect(curphys) THEN PRINT "That is too big for the room you have left on the drive! Try a smaller number!" tempbig2=-1. ENDIF IF LAND(tempmod(23),2)<>0 AND tempbig2/cylsize+desccyl>4096. THEN PRINT "That makes it >4096 cylinders (too big for the driver)! Try a smaller number!" tempbig2=-1. ENDIF ENDWHILE ENDIF IF tempbig2=-1. THEN tempbig2=.0 ENDIF maxsect(curphys)=maxsect(curphys)-tempbig2 desct0s=tempbig2 PRINT "Final partition size is "; (desccyl*cylsize+tempbig2)/4.; " KB (" ; (desccyl*cylsize+tempbig2)/4096.; " MB)." (* These two must always match the physical drive, or calcs will get extremely (* messy. deschead=FLOAT(totalhead(curphys)) descsct=FLOAT(totalsect(curphys)) (* Put descriptor name into temp descriptor temp="" WHILE LEN(temp)=0 OR LEN(temp)>3 DO INPUT "Name of device descriptor you are creating (3 chars max):" ,temp IF LEFT$(temp,1)="/" THEN temp=RIGHT$(temp,LEN(temp)-1) ENDIF ENDWHILE FOR counter=1 TO LEN(temp) tempmod(50+counter)=ASC(MID$(temp,counter,1)) NEXT counter tempmod(50+LEN(temp))=tempmod(50+LEN(temp))+$80 (* cylinders tempmod(24)=PEEK(ADDR(desccyl)) tempmod(25)=PEEK(ADDR(desccyl)+1) (* heads tempmod(26)=deschead (* OS9 sectors / track tempmod(28)=PEEK(ADDR(descsct)) tempmod(29)=PEEK(ADDR(descsct)+1) (* T0S (now used for extra sectors beyond CHS limits (for LBA, mainly)) tempmod(30)=PEEK(ADDR(desct0s)) tempmod(31)=PEEK(ADDR(desct0s)+1) (* partition offset tempmod(39)=PEEK(ADDR(partitionstart)) tempmod(40)=PEEK(ADDR(partitionstart)+1) (* Calculate CRC regs.x=ADDR(tempmod(1)) regs.y=53 regs.u=ADDR(tempmod(54)) RUN Syscall($17,regs) FOR counter=54 TO 56 tempmod(counter)=LNOT(tempmod(counter)) NEXT counter outfilename=temp+".dd" CREATE #outfile,pathname+"/"+outfilename:WRITE PUT #outfile,tempmod (* Assign tempmod to proper moddata(#) moddata(tempmod(20)+1)=tempmod CLOSE #outfile usedflag(tempmod(20)+1)=TRUE PRINT "Descriptor written as "; outfilename lastparttype=tempmod(20)+1 currentpart=currentpart+1 EXITIF maxsect(curphys)<=.0 THEN ENDEXIT ENDWHILE IF maxsect(curphys)>.0 THEN PRINT "Warning: Finished all the partitions you requested with " ; maxsect(curphys) PRINT "sectors left UNUSED on the drive!" ENDIF (* May want to add something to go back and do other physical drive? IF foundphys<2 THEN dummy="" WHILE dummy<>"Y" AND dummy<>"y" AND dummy<>"N" AND dummy<>"n" DO INPUT "Do you wish to create a 2nd drive at this time (y,n):",dummy ENDWHILE IF dummy="Y" OR dummy="y" THEN PRINT "Re-reading current device descriptors..." GOSUB 3000 GOTO 7 ENDIF ENDIF END (* Manual prompt for cyl/head/sector 1000 PRINT "CHS mode properties:" INPUT "What is the total # of cylinders on the drive:",totalcyl( curphys) IF lbaallowed(curphys)="N" AND totalcyl(curphys)>4096 THEN PRINT "WARNING: Current CCIDE driver can only handle 4096 cylinders maximum for a CHS" PRINT "mode only drive - make sure none of your descriptors use more than 4096" PRINT "cylinders." ENDIF PRINT "What is the total number of heads on the drive: "; maxsel=16 GOSUB 2000 totalhead(curphys)=c INPUT "What is the total number of 512 byte sectors/track on the drive:" ,totalsect(curphys) chssectors(curphys)=totalcyl(curphys)*totalhead(curphys)*totalsect (curphys) RETURN (* Generic 1-9 select routine (* Entry: maxsel=maximum allowed 2000 c=0 WHILE c<1 OR c>maxsel DO PRINT "Select <1-"; maxsel; ">:"; INPUT "",c ENDWHILE RETURN (* Clear all logical and physical device flags 3000 FOR c=1 TO maximumdrive usedflag(c)=FALSE NEXT c physused(1)=FALSE physused(2)=FALSE foundphys=0 RETURN (* Initialize a descriptor in tempmod (* Module sync bytes 4000 tempmod(1)=$87 tempmod(2)=$CD (* mod size tempmod(3)=$00 tempmod(4)=56 (* Module name offset tempmod(5)=$00 tempmod(6)=50 (* Type/Language tempmod(7)=$F1 (* Attributes/Revision tempmod(8)=$81 headerparity=tempmod(1) FOR counter=2 TO 8 headerparity=LXOR(headerparity,tempmod(counter)) NEXT counter headerparity=LNOT(headerparity) (* Header parity check tempmod(9)=headerparity (* File manager name offset tempmod(10)=$00 tempmod(11)=42 (* Device driver name offset tempmod(12)=$00 tempmod(13)=45 (* Mode byte tempmod(14)=$FF (* Device controller 24 bit address tempmod(15)=$07 tempmod(16)=$FF tempmod(17)=$00 (* Initialization Table size (size of moddata part only) tempmod(18)=$18 (* Device type (1=RBF) tempmod(19)=$01 (* Drive # (logical drive # for current controller address) tempmod(20)=$00 (* Stepping rate (unused for IDE) tempmod(21)=0 (* Device type (hi bit set is hard drive (non-removable media?)) tempmod(22)=$80 (* Density (Bit 0=physical drive #, Bit 1=LBA/CHS (CHS=1) tempmod(23)=$00 (* NOTE: If the driver detects an LBA mode capable drive, then the cyls, (* heads & sectors/track are only used by LFORMAT. The OFS will be the # (* of 65536 256 byte sector blocks from the start of the drive the current (* descriptor starts at. The # of sectors allowed for the drive will come (* from LSN0 (* Cylinders (will be used for total sector calculation if LBA mode used) tempmod(24)=0 tempmod(25)=0 (* Heads (will be used for total sector calculation if LBA mode is used) tempmod(26)=0 (* Disk verify (0=ON) tempmod(27)=1 (* Sectors/track tempmod(28)=0 tempmod(29)=0 (* Sectors/track on track 0 (used for LBA size adjustment by LFORMAT) tempmod(30)=0 tempmod(31)=0 (* Sector Interleave (unused by IDE) tempmod(32)=1 (* Minimum sector allocation size (# of sectors) tempmod(33)=$20 (* Padding to match DMODE from Eliminator tempmod(34)=$00 tempmod(35)=$00 tempmod(36)=$00 tempmod(37)=$00 (* Write precomp cylinder code (unused by IDE) (wpc=) tempmod(38)=$00 (* Partition offset - cylinder offset if CHS, (sector*65536) if LBA (* Driver currently not intelligent enough to check vs. any other partitions (* on same drive...may change later. 1st partition usually starts at (* $0000 in both cases. (ofs=) tempmod(39)=$00 tempmod(40)=$00 (* Reduce Write Current (unused in IDE) (rwc=) tempmod(41)=$00 tempmod(42)=$00 (* File manager name (always 'RBF') tempmod(43)=ASC("R") tempmod(44)=ASC("B") tempmod(45)=ASC("F")+$80 (* Device driver name (always 'CCIDE') tempmod(46)=ASC("C") tempmod(47)=ASC("C") tempmod(48)=ASC("I") tempmod(49)=ASC("D") tempmod(50)=ASC("E")+$80 (* Device Descriptor name (reserves room for 3 chars) hi bit set on last tempmod(51)=$00 tempmod(52)=$00 tempmod(53)=$00 (* CRC - Polynomial is $800FE3. To calculate it use F$CRC system call tempmod(54)=$FF tempmod(55)=$FF tempmod(56)=$FF RETURN (* Print out current status of drive info 5000 PRINT "Logical drive #'s used so far are:"; foundlog=0 FOR c=1 TO maximumdrive IF usedflag(c)=TRUE THEN foundlog=foundlog+1 PRINT c-1; " "; ENDIF NEXT c PRINT PRINT "Physical drive #'s used so far are:"; foundphys=0 IF physused(1)=TRUE THEN PRINT "0 (Master) "; foundphys=foundphys+1 ENDIF IF physused(2)=TRUE THEN PRINT "1 (Slave) "; foundphys=foundphys+1 ENDIF PRINT (* Print out some specific drive info based on moddata stuff PRINT "Current active setup: (NOTE: all sectors listed are 256 byte OS9 Sectors!)" IF foundlog>0 THEN FOR c=1 TO maximumdrive IF usedflag(c)=TRUE THEN IF lba(c)="" AND LAND(moddata(c).offset(23),2)=0 THEN WHILE lba(c)<>"Y" AND lba(c)<>"N" DO PRINT "Is your logical drive #"; c-1; " running in LBA mode (y,n):" ; INPUT "",lba(c) IF lba(c)="y" THEN lba(c)="Y" ELSE IF lba(c)="n" THEN lba(c)="N" ENDIF ENDIF ENDWHILE ENDIF GOSUB 5050 ENDIF NEXT c ELSE PRINT " NO ACTIVE DRIVES" ENDIF RETURN (* Print stats of logical drive entry #c 5050 PRINT ulineon; "Logical drive #"; moddata(c).offset(20); " (physical drive #" ; LAND(moddata(c).offset(23),1); ")"; ulineoff PRINT " Force CHS is "; IF LAND(moddata(c).offset(23),2)=0 THEN PRINT "off, "; ELSE PRINT "on, "; ENDIF PRINT "cyl="; moddata(c).offset(24)*256.+moddata(c).offset(25); ", heads=" ; moddata(c).offset(26); ", sct/trk="; moddata(c).offset(28)*.256 +moddata(c).offset(29); ", "; PRINT "extra sectors="; moddata(c).offset(30)*256.+moddata(c).offset (31) PRINT " Partition starts at "; IF LAND(moddata(c).offset(23),2)=1 OR lbasectors(c)=.0 THEN PRINT "cylinder "; ELSE (* add checks here for if drive supports LBA or not PRINT "32 MB block #"; ENDIF PRINT moddata(c).offset(39)*256.+moddata(c).offset(40); " " RETURN (* Rename old device descriptors for both drives 5990 FOR tempnum=0 TO 1 GOSUB 6000 NEXT tempnum RETURN (* Rename old device descriptors from '.dd' to '.dd.old' for physical drive (* tempnum 6000 PRINT "Renaming old device descriptors for physical drive #" ; tempnum-1 FOR c=1 TO maximumdrive IF LAND(moddata(c).offset(23),1)=tempnum AND usedflag(c)=TRUE THEN temp=olddescfile(c).name FOR counter=1 TO 29 EXITIF ASC(MID$(olddescfile(c).name,counter,1))>$80 THEN ENDEXIT NEXT counter shellline="RENAME "+pathname+"/"+LEFT$(olddescfile(c).name,counter -1)+"d "+LEFT$(olddescfile(c).name,counter-1)+"d.old" PRINT shellline SHELL shellline ENDIF NEXT c RETURN (* Get current count of used logical drives 7000 foundlog=0 FOR c=1 TO maximumdrive IF usedflag(c)=TRUE THEN foundlog=foundlog+1 ENDIF NEXT c RETURN (* Calculate minimum cluster size (* entry:tempbig2=total # of sectors 8000 c=2 REPEAT EXITIF 2^c>tempbig2 THEN ENDEXIT c=c+1 UNTIL 2^c=128. PRINT 2^c RETURN (* Display currently selected physical drive, or prompt for one if none (* Entry: curphys=physical drive #+1 (0=none) (* Exit: curphys=selected drive (* tempmod(23) has physical drive bit OR'd in (* physused(curphys) & foundphys updated only if routine entered with (* no drive selected 9000 IF curphys=0 THEN PRINT "Which physical drive number are you making descriptor(s) for:" PRINT "<1> Master (physical drive #=0)" PRINT "<2> Slave (physical drive #=1)" maxsel=2 GOSUB 2000 IF physused(c)=TRUE THEN PRINT "WARNING: You already have descriptors pointing to that drive. Are you sure (y,N):" ; dummy IF dummy<>"Y" AND dummy<>"y" THEN PRINT "Aborted." END ENDIF ENDIF physused(c)=TRUE curphys=c foundphys=foundphys+1 ENDIF tempmod(23)=LOR(tempmod(23),c-1) IF curphys=1 THEN PRINT "Master (physical drive #0) selected" ELSE PRINT "Slave (physical drive #1) selected" ENDIF RETURN