I #X;save#d:MDOS3.M65 MYDOS moduleX;X; DOS MAKE DIRECTORY CODE(X;29X; Copyright 1984, Charles Marslett, Wordmark Systems<X;FIX; Permission is granted by the author for any use whatsoever of thisPHX; code, so long as this notice remains in the source code, and soZLX; long as the source to this routine, however modified or unmodified,d.X; is made available for a nominal cost.nX;x-X; XIO FUNCTION TO CREATE A NEW DIRECTORYX;X; PARSE DIRECTORY NAMEX;MKDIR GETFNM" SFDIR;;FIND FILE IN DIRECTORY EMKDMRDQ>;;FILE ALREADY EXISTS ;;SKIP 2 BYTESDISFULQ>;;DIRECTORY FULL !AEXITX;X; READ IN BIT MAPX;MKDMRDQHOLFN GDISFUL RBITMP" %MAPBUF,161@ 'DATBYTJX;T'X; FIND EIGHT SECTORS FOR DIRECTORY^X;h3Q>q;;FIRST AVAILABLE SECTOR AFTER ROOT DIR.r PCURSEC9| Q>qPCURSEC9Q> PTMP1FDIRLP#TMP1" FNDLBIT;;IS THIS SECTOR FREE? EFDIR2 MMAPBUF8 DFDIR1FDIR2MMAPBUF8FDIR1HFDIR3 PTMP1FDIR3 INCCSEC QTMP1R> HFDIRLPX;& X; ALLOCATE THE SECTORS USED0X;:ALCDLP DECCSECD FNDLBITNN>X EALCPG2b MMAPBUF8l PMAPBUF8v DALCPG1ALCPG2MMAPBUF8PMAPBUF8 VMAP2MODALCPG1 DECCNT "TMP1 HALCDLPX;(X; WRITE ALLOCATION MAP BACK TO DISKX; FMTMAPX;5X; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORYX; QHOLFN  SDIRBK;  ENTNAME*QCURSEC94PDIRBUF8> QCURSEC9HPDIRBUF8RQ>\PDIRBUF8fQ>pPDIRBUF8zT? SAVFLAGX;X; THEN CLEAR NEW DIRECTORYX;Q> PFMSBPT QCURSEC9%CURSEC9 !CLRDIRX;$X; SIMULATE OLD STYLE BIT FINDERX;FNDLBIT FNDBIT5;;SAVE MASKQTMP2;;FIRST PAGE? FFNDPG0$'TMP2;;SAVE OFFSET IN PAGE. RDATBYT8 EDFEJMPB RDNXTM;;READ IN PROPER PAGEL$%TMP2;;THEN RESTORE A AND Y REGSV7`!;;;SET CY (PAGE 1 BUFFER USED)j:tX;~FNDPG07;;RESTORE SAVED MASK,;;AND CLR CY (SAY PAGE 0):X;DFEJMP!DFERRX;DECCSECQCURSEC9 HALCPG0"CURSEC9ALCPG0"CURSEC9:X;INCCSEC#CURSEC9 HDELDIN #CURSEC9 DELDIN:X;(X; DOS DIRECTORY ROUTINES2X;<X;F/X; OPEN A DIRECTORY (FOR DIRECT USER ACCESS)PX;ZLSTDIR%> dSAVFNBQFNAME 8n P@FMSBPT7x3 ISAVFNB) SFDIR;;FIND A MATCH IN THE DIRECTORY-EENDDIR;;IF NO MORE, GO REPORT FREE SPACE1NXTDIR FMTDIR;;ELSE, FORMAT INTO TEXT STRING QCURFNO-PFCBFNO9;;SAVE FILE NUMBER OF ENTRY FOUNDGODONE!DONE;;AND RETURNX;1GOTEOD"DATBYT;;CONVERT EOL TO $9B (REAL EOL)PCURLEN9;;AND FINISH UP HGODONEX;X;DIRRD%> | FGOTEODR>;;IS THIS END OF LINE?'HGODONE;;IF NOT, CONTINUE TEXT DUMP QFCBFNO9 RCURFNO HDMSTRD (DIUNIT FDRDNRQDMSTRD RRDIRDRDNRQ CSFDIR DNXTDIRX;0X; NO MORE ENTRIES, REPORT FREE SECTORS LASTX;&ENDDIR RBITMP;;READ THE VTOC DATA%>%'CURMAP;;FORCE A REREAD NEXT TIME&QMAPBUF0:$MAPBUF;;AND STUFF BUFFER WITH NUMBER OF FREE SECS.: CVTDECD$>N9FSECLQFSECM9;;FOLLOWED BY "FREE SECTORS" TEXTX P@FMSBPT7b3l2v HFSECL#FGODONE;;THEN LAST LINE IS DONEX;:DIREOF!RETEOF;;NO MORE LINES, RETURN E-O-F INDICATIONX;FSECM A FREE SECTORSA=X;/X; FORMAT A DIRECTORY ENTRY FOR BASIC, ETC.X;FMTDIR%> ;;space $DIRDSP QDIRBUF95M>  FNOTLCK %> *;;IF SO, MARK AS LOCKED NOTLCKC %>* P@FMSBPT747>%> ;;spaceHM>R FNOTDIR\%> :f NOTDIRCp%>z P@FMSBPT7 CPYNAML3QDIRBUF9 P@FMSBPT72)>  DCPYNAMLX;Q> ;;space P@FMSBPT7 %DIRDSPQDIRBUF8$DIRBUF8!%>;;SECTOR COUNT STARTS HERE X; 8X; CONVERT A 16-BIT INTEGER TO A 4 OR 5 DIGIT NUMBER X;$ CVTDEC&TMP2. PTMP18 $>'B Q>'L MKDGT2V R> 0` HSKIP5j 1t SKIP5$>~ Q> MKDGT2 Q>d;;FOR SHORT STUFF MAKDGT Q> MAKDGT A O> 0 P@FMSBPT7 3 Q>;;TERMINATE LINE PDATBYT P@FMSBPT7 Q> $CURFCB PCURLEN9 :( X;2 ;;IF SUBTRAHEND < 256, ZERO UPPER BYTEP MKDGT2&DIRDSPZ PDIRSECd 'DATBYTn %> 0x ; DGTLP2QTMP1 SDIRSEC > QTMP2 SDIRDSP DDGTXIT PTMP2 &TMP1 3 EDGTLP2 X; DGTXITC %DATBYT P@FMSBPT7 3 :" X;, @X; PARSE A FILE NAME WITH WILD CARD CHARACTERS ('*' AND '?')6 X;@ GETNAM23;;look for ">" inJ Q@ICBALZ7;;the start ofT R> >;;the filename^ FGETNAMh 1r HGETNAM;;branch always| X; GETFNM$CURFCB %>i Q>i SETDIR 3 Q@ICBALZ7 3 R> :;;DEFAULT DIRECTORY? HGETNAM2 1 'TMP1 %DEFAULT 'ICDNOZ C PICDNO9 SETUPD& QCDIREC0 %CDIREC: SETDIRD %TMP1N X;X GETNAM$> b 3l AFTSTRQ@ICBALZ7v R> * HTSTPER Q> ? 3 QLOOPPFNAME 9 2 ITOXITC;;END OF EXTENSION? "PERFND(>;;END OF FILE NAME? HQLOOP;;NO MORE -?-S FAFTSTR X; TSTPERR> .;;A PERIOD? 4HTSTCHR;;IF NOT, CHECK FOR INDIVIDUAL CHARACTERS Q> ;;IF SO, FILL WITH SPACES 3 HPERFND X; TSTCHRR> ?* &DENDCHR;;IF < '?', CHECK FOR DIGIT4 1R> Z;;ELSE, UPPER CASE LETTER, '?', OR '@'?> DGOTCHRH R> _R *DENDCHR;;IF CARET, BACKSL. OR BRACKETS\ -R> z;;LOWER CASE, ACCENT OR UNDERSCORE?f DGOTCHRp %ENDCHR(> ;;IF FIRST CHAR, ERRORz "FERRCHR;;NO BYTES IN FILE NAME R> 0;;ELSE, A DIGIT? (DFILLNM;;IF NOT, THIS IS END OF NAME R> : EFILLNM X; GOTCHRPFNAME 9 3 2 GAFTSTR X; TOXITCQ@ICBALZ7 TSTDIRR> :;;look for MYDOS FMYDIR;;or SpartaDOSR> >;;directory separator HXITCHRMYDIR'TMP2$ SFDIR;;ELSE, FIND FILE.EFNER1;;NO SUCH FILE8 TONXDRB FFNER1L %TMP2V HGETNAM`'FNER1Q>;;IF NOT, RETURN ERROR 174j ,;;BIT ABS (SKIP 2 BYTES)tX;~ERRCHRQ> !AEXITX; FILLNM5Q> ;;spaceFILLLPPFNAME 92 GFILLLP7 !TSTDIRX;7X; RETURN WITH NON-ZERO FLAG IF FILE IS A DIRECTORYX;(TONXDRQ>;;FILE FOUND, A DIRECTORY?  GETFLAG"FTONXIT;;IF NOT, SET ZERO FLAG4QDIRBUF8;;YES, MOVE POINTERS TO THE NEW LEVEL( PDIRBAS92QDIRBUF8<PDIRBAS9FQ>;;AND CLEAR ZERO FLAGP TONXIT:ZX;d8X; ENTER A NAME INTO THE DIRECTORY AT DIRBUF[DIRDSP]nX;x ENTNAME6$>  %DIRDSP2NAMELPQFNAME 9;;LOAD THE MASK CHARACTERR> ?'HSTORIT;;IF NOT '?', SAVE IT AS IS!863DNOSTOR;;IF CY CLEAR, LEAVE CHARACTER UNCHANGED,Q> ;;ELSE, IF CY SET, CONVERT '?' TO ' 'STORITPDIRBUF8 NOSTOR32 GNAMELP8 %DIRDSPXITCHR$CURFCB":,X;6)SFDIR WBITMP;;INSURE BIT MAP IS SAFE@$>J &HOLFNT &CURFNO^2h &DAUX2r2| &DAUX1 $>READ &DCOMND8 SYSSET;;SET UP POINTERS, ETC. FOR A NEW DISK ACCESS QICDNOZ RRAMDKU.FCSFDIR;;IF RAMDISK, FORGET DENSITY CHECK! $CURFCB;;don't read boot sec"QDIRBAS9;;if in subdirectories$R>i;;but allow if first read HCSFDIR- DSKINV;;ELSE, READ THE FIRST BOOT SECTOR GERRX( INVUNIT;;UPDATE DRIVE CONFIGURATIONX;0CSFDIR#CURFNO;;READ NEXT 16-BYTE DIR. BLOCK QCURFNO&/ BSECDS;;CONVERT TO SECTOR AND DISPLACEMENT0XITCHR1EXITCHR:%HNOREAD;;IF DISP>0, PROCESS BLOCKD# RDIRBK;;IF DISP=0, READ SECTORNX;XNOREAD%DIRDSPb QDIRBUF8l7FFNDOLD;;ZERO IS END OF DIRECTORY (NO MORE ENTRIES)v;GFNDOLD;;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE ENTRIES)M>;;preserve lock flag R>;;is this DOS 2.5 + file?HNOD25;;nopeQ>A;;otherwise, kludge theNDIRBUF8;;flag to make $42PDIRBUF8;;and save lock. NOD25M>8HCSFDIR;;IF OPEN/CREATE FILE, IT IS NOT REALLY HERE!$> CPNXCHQFNAME 9R> ?#FWCMTCH;;EVERYTHING MATCHES '?'RDIRBUF84HCSFDIR;;IT DOES NOT MATCH, LOOK AT THE NEXT ONE  WCMTCH32  GCPNXCH*,4*DXITCHR;;ENTRY FOUND, RETURN WITH CY=0>X;HFNDOLD$HOLFNR9IKPOLD;;IF AN EMPTY SLOT IS ALREADY FOUND, DO NOTHING\ $CURFNOf5&HOLFN;;ELSE, SAVE THE SLOT NUMBER (FIRST EMPTY!)p KPOLD>z2GCSFDIR;;IF NOT END OF DIRECTORY, KEEP LOOKING ERRX;5EXITCHR1;;ELSE, ENTRY NOT FOUND, RETURN WITH CY=1X;X; DOS I/O ROUTINESX;X;X; DISK SECTOR I/O ROUTINESX;!WRDISK;;;FMS DISK WRITE ENTRY0RWDISK%FMSBPT;;DATA SECTOR READ/WRITE ENTRYQFMSBPT BUFSETQCURSEC9 %CURSEC9 FMDKIO6 $DUNIT$ (RAMDKU. FRDKIO188B5LQSECSIZ9V>`7j !DKIOtRDKIO1!RDKIO;;was moved...~X;EXTEND ALLOC QFCBOTC9V? DREWRIT "FCBOTC9 WTRICK !WRTTSTX;REWRIT%LNKSEC9 QLNKSEC9 SAVLNKWRTTSTGRTBADF #SECCNT9  HTONXT#SECCNT9X;($TONXTQLNKSEC9;;MAKE NEXT SECTOR2PCURSEC9;;NEW CURRENT SEC.<QLNKSEC9FPCURSEC9PQ>ZPLNKSEC9;;ZERO LINKdPLNKSEC9n(LENSETPCURLEN9;;ZERO CURRENT OFFSETxQDLINK;;GET THE LINK LOC.PMAXLEN9;;MAKE IT MAX. LEN.,;;CLEAR CY FOR LATER READ:X;RDNXTSQFCBFLG9 FCHASEX;WRNXTSQFCBFLG9 GEXTENDT? IRDNXTST? PFCBFLG9 WRDISK IRDNXTSX;"8RTBADF!HWERR;;RETURN HARDWARE ERROR CODE IF PRESENT,X;6 SAVLNK5@CJ %DLINKT P@FMSBPT7^7h3r P@FMSBPT7|3 QCURLEN9NOBITP@FMSBPT7 %FCBOTC9GLEN16;;16-BIT LENGTH? QFCBFNO9T?T? %DLINK L@FMSBPT7 P@FMSBPT7LEN16!WRDISKX;WTRICKQLNKSEC9 PSAVSEC9QLNKSEC9PSAVSEC9& &LSTIOCB0 QCURSEC9: PLSTSECDQCURSEC9NPLSTSECX !WRDISKbX;lINSTRT INITYPvX;CHASEQLNKSEC9LLNKSEC9 FNOLINK TONXT;;SET CY=0, FUNC=READ RWDISK4GRTBADF;;CANNOT READ SO BAD FILE NUMBER(ERR=164) %DLINKQFCBOTC9;;16-BIT LINK?L> GLNGLNK Q@FMSBPT7V?V? RFCBFNO9  HXLINKEDQ> LNGLNKM@FMSBPT7*PLNKSEC943> Q@FMSBPT7H PLNKSEC9R3\ Q@FMSBPT7f PMAXLEN9p DRDXIT,z:X;XLINKEDQICCOM9R>FMTCMD;;IS THIS A FORMAT? HFNOERR NOLINK;:X;%X; READ OR WRITE A DIRECTORY BLOCKX;RRDIRQFCBFNO9X;SDIRBKPCURFNORDCFNOQCURFNO BSECDSX;1RDIRBK WBITMP;;TAKE CONTROL OF SYSTEM BUFFER$,. ;;LDA # (SKIPS 1 BYTE)8 WDIRBK;B RWDBK6L$CURFCB;;PUT FCB NO. IN XV&&DIUNIT;;SAVE THE DIR. BUFFER IOCB` SYSSETj,t QDIRSEC~ ODIRBAS9?QDIRBAS9!O>;;MULTIPLE DIRS. REQ. THIS8SYSRW FMDKIO IDRDXIT3Q>;;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODE ;;SKIP 2 BYTESX;FNOERRQ> PDSTATS !HWERR;;FILE NUMBER MISMATCHX; +X; READ OR WRITE THE DISK VTOC (BIT MAP)X;RBITMPQCURMAP( RICDNOZ2.FMAPXIT;;IF WE READ WHAT IS ALREADY THERE!<9 WBITMP;;ELSE, REAL I/O, SAVE CURRENT BUFFER CONTENTSFX;PQ>Z?d'ZMAPPMAPBUF8;;THEN ZERO ENTIRE 512n#PMAPBUF8;;BYTES OF MAP BUF.x1 HZMAP,4 RWBMAP;;THEN READ 128 OR 256 BYTES OF VTOC DATAX;%>8'DIUNIT;;INDICATE MAP IS LOADED (NOT DIRECTORY DATA)1'MAP2;;INDICATE NO DATA IN SECOND PAGE OF MAP3&'CHGMAP;;INDICATE MAP IS UNCHANGED3 'MAP2MOD 'CURMPX;8MAPCLRPCURMAP;;AND SAVE DRIVE NUMBER MAP APPLIES TO MAPXIT:X;"WBITMPQCHGMAP,0FMAPCLR;;IF MAP NOT CHANGED, SKIP WRITING IT6 PDUNIT@FMTMAPQ>J!PCHGMAP;;ELSE, MARK IT UNUSEDT PCURMAP^QDUNIT;;save drive #h5r ;;;SET CY TO INDICATE A WRITE|3 RWBMAP;;AND CALL THE READ/WRITE SECTOR ROUTINE7;;restore drive # PDUNITX;WRNXTMQMAP2MOD)HNOMAPI2;;IF THE PAGE BUFFER IS CLEANQ>;;JUST EXIT, ELSE5 QMAP2 #MAP2MOD;)EMUSTWM;;WRITE IT TO DISK (CY IS SET)X;9RDNXTMRMAP2;;READ A PAGE INTO THE SECOND PAGE BUFFER.FNOMAPI;;IF IT IS ALREADY THERE, JUST EXIT54 WRNXTM;;ELSE, WRITE CURRENT PAGE (IF NECESSARY)&7;; AND READ IN THE NEW ONE05:.,;; BY FALLING INTO MUSTWM WITH CY CLEAREDDX;N MUSTWM5XQ>MAPBUF b%>MAPBUF l3 BUFSET;;SET UP BUFFER POINTERS FOR SECOND PAGEv7;; OF VTOC BUFFER# MAPIOC;;ISSUE I/O OPERATION(S)77PMAP2;;UPDATE ID FOR CONTENTS OF SECOND PAGE BUFFER NOMAPI:X;9RWBMAP SYSSET;;SET UP BUFFER POINTERS FOR SYSTEM I/OQ> MAPIOC65$QSECSIZ9>7(>;;256 BYTE SECS?  FMAPDDS-T?;;128, CHANGE PAGE NUMBER TO PAIR NUMBER MAPDDSN>*;4 O>h>?H!(>;;128 OR 256 BYTE SECTORS?R2FDDMAPX;;IF 128, READ 2 SECTORS TO FILL BUFFER\ Q>hf8p6z& SYSRW;;READ OR WRITE FIRST SECTOR QMAPBUF.R>;;IF DOS 2.0 DISK, ONLY ONE SECTOR EVEN!DXITMBF;; IN SINGLE DENSITY! STEPBP1DDMAPXQ>h86/ SYSRW;;READ OR WRITE SECOND OR ONLY SECTOR XITMBF8NOMAPI2QICDNOZ.PDUNIT;;RESTORE USER DRIVE NUMBER TO DUNIT0:;;SINCE THIS MAY HAVE BEEN ON ANOTHER DRIVE!X;/SYSSETQ>MAPBUF;;SET UP BUFFER POINTERS%>MAPBUF$ !BUFSET.X;8EX; ROUTINE TO STEP TO THE NEXT DIRECTORY ENTRY (UNTIL WE RUN OUT)BX;LBSECDS%>V 'DIRDSP`V?j WDIRDSPtV?~ WDIRDSPV?9WDIRDSP;;(FILE NUMBER MOD 8) * 16 IS OFFSET IN SECTOR+PDIRSEC;;FILE NUMBER/8 IS SECTOR OFFSETX;R>;;END OF DIRECTORY?16EBSECXT;;IF SO, RETURN CARRY SET (VALUES ARE BAD!)3WDIRDSP;;FINAL SHIFT SO NUMBER IS *16 (NOT *32) BSECXT:X;X; DOS ALLOCATION ROUTINESX;X; !X; FREE A SECTOR FOR LATER USEX;1FREE RBITMP;;MAKE SURE WE HAVE THE RIGHT MAP( PCHGMAP29FMTFRE#MAPBUF;;BUMP LOW BYTE OF FREE SECTOR COUNT<HFREE0;;IF NO CARRYF#MAPBUFPFREE0 FNDBITZ5d QTMP2n FSBMP1x 'TMP2RCURMP;;BEFORE FIRST HOLE?ESBMP2;;NO, LEAVE UNCHANGEDPCURMP;;YES, NEW FIRST HOLESBMP2 RDNXTM %TMP2"VMAP2MOD;;MARK MAP PAGE2 DIRTY7LMAPBUF8PMAPBUF8:X; SBMP17 LMAPBUF8 PMAPBUF8:X;"3X; FIND BIT ASSOCIATED WITH A SECTOR ON THE DISK,X;6FNDBITQCURSEC9@M>;;EXTRACT THE BIT NUMBERJ?T;^Q>h.FREE1W?;;POSITION CARRY TO THE BIT TO FLIPr1| IFREE15;;SAVE THE BIT MASKX; QCURSEC9,$O> ;;ALLOW FOR 10 BYTE HEADER?;;SAVE LOW BYTEQCURSEC9O>;;PROPOGATE CARRYW?;;fix 65535 sector bug PTMP2CW? VTMP2 W? VTMP2 W?& ?0 X;: 7;;RESTORE THE BIT MASKD :N X;X )X; ALLOCATE AN UNUSED SECTOR TO A FILEb X;l ALLOC RBITMPv PCHGMAP %> Q> PTMP2 !ALL1RMAPBUF8;;ANY BITS LEFT? HSECFN1;;IF SO 3 HALL1 X; ; QMAPBUF SCURMP ; S>! PTMP1 !ALLCKGALGONE! QCURMP ! PTMP2*! RDNXTM4!Q>>!?H!ALL2RMAPBUF8R!1HSECFN2;;IF FREE SECTOR IN SECOND PART OF MAP\!3f! HALL2p!%#CURMP;;TO NEXT SECTOR OF BIT MAPz! "TMP1! IALLCK!X;!ALGONE"CURMP!#DFERRQ>;;DISK FULL ERROR CODE!%!AEXIT;;IF THIS IS IT, ERROR-EXIT!X;! SECFN1;!$>;;I.E., -8*10 - 1! ALL3W?!2! RMAPBUF8! DALL4!," HALL3"ALL4NMAPBUF8" PMAPBUF8$" IALL7."X;8" SECFN2;B"$>;;I.E., -8*10 - 1L" ALL5W?V"2`"RMAPBUF8j" DALL6t",~" HALL5"ALL6VMAP2MOD"NMAPBUF8"PMAPBUF8"X;" ALL7C"T?" UTMP2"T?" UTMP2"T?" UTMP2" PTMP1#A # OTMP1# $CURFCB# PLNKSEC9(# QTMP22#O><#PLNKSEC9F#DECCNTQMAPBUFP# HNOBORZ#"MAPBUFd#NOBOR"MAPBUFn#,x#:#X;#X; DOS MISC. SUBROUTINES#X;#X;#%X; SET UP STATE VARIABLES ON ENTRY#X;#SETUP%ICDNOZ;;GET UNIT NO.#SETUPW&CURFCB#@#2#2#1&STKPSV;;SAVE POINTER TO RETURN ADDR ON STACK#'SETUPD'DUNIT;;COPY UNIT NO. TO DCB$Q>$ )RAMDKU$4FUFIXED;;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES"$QSECSIZ8,$9FINVUNIT;;IF NOT VALID UNIT, TEST FOR CURRENT DENSITY6$@UFIXEDPSECDAT;;OTHERWISE, STORE CORRECT DENSITY INFORMATION@$V?J$W?T$W?^$4L>};;AND UPDATE LINK POSITION IN THE DISK SECTORh$ PDLINKr$X;|$ $CURFCB$"%BUFNO9;;GET THE BUFFER NUMBER$ HRSETUP$#%FILES;;IF ONE IS NOT ALLOCATED$3$ SFORB1$6FNOSECB;;ALLOCATE ONE, OR ABORT THE OPERATION NOW!$QBUFFLG8$ HSFORB$Q>$PBUFFLG8$C$ PBUFNO9$RSETUPQDOSEND;;==SBTABL%3PFMSBPT;;STORE THE BUFFER POINTER FOR THIS FILE%4QSBTABU8;; IN THE ZERO PAGE POINTER "FMSBPT"%PFMSBPT&%:0%X;:%(INVUNIT JSTRD;;TEST FOR DRIVE STATED%5HUFIXED;;IF IT IS ACCESSABLE, RETURN REAL DENSITYN%X;X%0NOUNITQ>;;RETURN ST=160, DRIVE NOT PRESENTb% ;;SKIP TO JMP INSTRUCTIONl%3NOSECBQ>;;RETURN ST=161, NO MORE FILE BUFFERSv% !AEXIT%X;%+X; REMOVE DOS POINTER FROM BOOT SECTORS%X;%'TDDOS TSTDOS;;MUST WE UPDATE BOOT?%HTDEXIT;;NO, RETURN%1DELDOS%>;;YES, REMOVE DOS POINTER FROM BOOT% FUPDBT%X;%&X; ADD DOS POINTER TO BOOT SECTORS%X;%SETDOS'DOSLOC%PDOSLOC% %SECDAT&UPDBTQDUNIT & RRAMDKU& FTDEXIT & 'SECDAT*& QDEFAULT4&5>&%>H& QFCBOTC9R&GNOAND;;LONG LENGTH FIELD?\&!%>;;IF NOT, USE ONLY 10 BITSf&NOAND'ANDCDp&Q>BOOTFLz&%>BOOTFL& BUFSET&%>& 'DAUX2& D12303& 'DAUX1&$>& &DEFAULT&;& DKIO2& STEPBP& )BOOTL& HD1230&7' PDEFAULT' %ICDNOZ' 'DUNIT$'QSECSIZ8.' PSECDAT8':B'X;L'STEPBPQDBUFLOV'N>`' PDBUFLOj' GTSTEODt' #DBUFHI~'X;'TSTEOD%DAUX1':'X;'%X; TEST FOR FILE NAME = 'DOS.SYS''X;'TSTDOS%> ' $DIRDSP'TDLOOPQDIRBUF9'NDOSSYS 8' HTDEXIT'2'3( HTDLOOP (TDEXIT$CURFCB(?(:((X;2(DOSSYS ADOS SYSA<(X;F(1X; FIND AT LEAST ONE FILE MATCHING GIVEN NAMEP(X;Z(1LFFILE GETFNM;;EXTRACT FILE NAME FROM BUFFERd('TMP2;;SAVE IT FOR -RENAME-n(+ SFDIR;;FIND FIRST MATCHING FILE IN DIRx("Q>;;IF NONE, RETURN ERROR 170(EAEXIT;;ELSE, RETURN(:(X;(%X; RETURN ERROR IF FILE IS LOCKED(X;(TSTLOKQ> ;;CHECK BIT 5( GETFLAG( FTDEXIT( Q>;;FILE LOCKED ERROR = 167( ;;SKIP 2 BYTES(X;(X; RETURN WITH NO ERROR(X;)DONEQ>;;NORMAL COMPLETION)X;)-X; RETURN ERROR CODE IN ACC TO CIO (IN Y)")X;,)(AEXIT$STKPSV;;RESTORE STACK POINTER6)B@))$CURFCB;;RESTORE IOCB OFFSET TO X-REGJ)"PICSTA9;;RETURN STATUS IN IOCBT)?;;RETURN STATUS IN Y-REG^)&QDATBYT;;POSSIBLY RETURN DATA HEREh)")>;;SET CY FLAG APPROPRIATELYr):|)X;)$X; RETURN HARDWARE ERRORS TO CIO)X;)$HWERRQ>;;fix VTOC updating bug) PCURMAP) PCHGMAP)*QDSTATS;;LOAD REAL DISK I/O ERROR CODE)'HAEXIT;;AND RETURN IT TO THE CALLER)X;)-X; RELEASE FCB AND RETURN NO-ERROR STATUS)X;)FREDON$CURFCB)7%BUFNO9;;FINISHED WITH THE SECTOR BUFFER, RETURN IT)&FDONE;;IF NONE ALLOCATED, SO WHAT!*Q>*4PBUFNO9;;OTHERWISE, IT'S NOT ALLOCATED ANY MORE!*PBUFFLG8&* FDONE0*X;:*+X; TEST OR CLEAR A BIT IN THE FLAG BYTED*X;N*GETFLAG%DIRDSPX* MDIRBUF8b*:l*X;v*1X; SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY*X;*SAVFLAG%DIRDSP* PDIRBUF8* !WDIRBK*X;