; SAVE#D:MDOS3.M65 ; ; ;*DOS DIRECTORY ROUTINES ; ;*OPEN A DIRECTORY (FOR USER) ; LSTDIR LDY #$80-11 SAVFNB LDA FNAME-$80+11,Y STA (FMSBPT),Y INY BPL SAVFNB JSR SFDIR ; FIND A MATCH ; ; IN THE DIR BCS ENDDIR ; IF NO MORE ; ; MATCHES, REPORT ; ; FREE SPACE NXTDIR JSR FMTDIR ; ENTRY FOUND, ; ; FORMAT INTO A ; ; TEXT STRING LDA CURFNO STA FCBFNO,X ; SAVE THE FILE ; ; NUMBER OF THE ; ; ENTRY FOUND GODONE JMP DONE ; AND RETURN ; GOTEOD DEC DATBYT ; CONVERT EOL TO ; ; $9B (REAL EOL) STA CURLEN,X ; AND FINISH UP BNE GODONE ; DIRRD LDY #$80-11 RSTFNB LDA (FMSBPT),Y ; FETCH BYTES ; ; OF PREVIOUSLY ; ; PARSED DIR ENTRY STA FNAME-$80+11,Y INY BPL RSTFNB LDA CURLEN,X BMI DIREOF ; EOF IF WE ; ; ALREADY REPORTED ; ; FREE SPACE TAY LDA (FMSBPT),Y STA DATBYT INC CURLEN,X CMP #$9C BEQ GOTEOD CMP #$9B ; IS THIS EOL? BNE GODONE ; IF NOT, ; ; CONTINUE FETCHING ; ; OLD BYTES LDA FCBFNO,X CMP CURFNO BNE DMSTRD CPX DIUNIT BEQ DRDNRQ DMSTRD JSR RRDIR ; IF SO, INSURE ; ; DIR BLOCK IS ; ; IN MEMORY DRDNRQ JSR CSFDIR ; AND FIND THE ; ; NEXT ENTRY BCC NXTDIR ; IF FOUND, LOOP ; ; BACK AND FORMAT IT ; ;*NO MORE ENTRIES, REPORT FREE ; SECTORS LAST ; ENDDIR JSR RBITMP ; READ THE VTOC LDY #0 STY CURMAP ; FORCE A REREAD ; ; NEXT TIME LDA MAPBUF+3 LDX MAPBUF+4 ; AND STUFF THE ; ; BUFFER WITH # ; ; OF FREE SECTORS JSR CVTDEC LDX #-14 FSECL LDA FSECM+14-256,X ; ; FOLLOWED BY THE ; ; "FREE SECTORS" TEXT STA (FMSBPT),Y INY INX BNE FSECL BEQ GODONE ; DIREOF JMP RETEOF ; NO MORE LINES, ; ; RETURN EOF ; ; INDICATION ; FSECM .BYTE " FREE SECTORS",$9C ; ;*FORMAT A DIRECTORY ENTRY FOR ; BASIC, ETC. ; FMTDIR LDY #$20 LDX DIRDSP LDA DIRBUF,X PHA AND #$20 BEQ D0E35 LDY #'* ; IF SO, MARK AS ; ; LOCKED D0E35 TYA LDY #0 STA (FMSBPT),Y PLA LDY #' AND #$10 BEQ NOTDIR LDY #': NOTDIR TYA LDY #1 STA (FMSBPT),Y CPYNAML INY LDA DIRBUF+5,X STA (FMSBPT),Y INX CPY #13 BCC CPYNAML ; LDA #' STA (FMSBPT),Y LDY DIRDSP LDA DIRBUF+1,Y LDX DIRBUF+2,Y LDY #14 ; SECTOR COUNT ; ; STARTS HERE ; ;*CONVERT A 16-BIT INTEGER TO A ; 4 OR 5 DIGIT NUMBER ; CVTDEC STX TMP2 STA TMP1 LDX # >10000 LDA # <10000 JSR MKDGT2 PHA ;* [D] CMP #'0 BNE SKIP5 DEY SKIP5 LDX # >1000 LDA # <1000 JSR MKDGT2 CMP #'0+1 ;* [D] PLA ;* [D] BCS SKIP4 ;* [D] CMP #'0 ;* [D] BNE SKIP4 ;* [D] DEY ;* [D] SKIP4 ; ;* [D] Skip4 ; [D] is David's code ; transplanted from 4.53 to ; 4.51 by Lee ; LDA #100 ; FOR THE SHORT ; ; STUFF JSR MAKDGT LDA #10 JSR MAKDGT TXA ADC #'0+10 STA (FMSBPT),Y INY LDA #$9B ; TERMINATE LINE STA DATBYT STA (FMSBPT),Y LDA #0 LDX CURFCB STA CURLEN,X RTS ; ;*CREATE A DIGIT AND STORE IT ; INTO THE DIRECTORY BUFFER ; MAKDGT LDX #0 ; IF SUBTRAHEND ; ; < 256, ZERO HI MKDGT2 STX DIRDSP STA DIRSEC STY DATBYT LDY #'0 SEC DGTLP2 LDA TMP1 SBC DIRSEC TAX LDA TMP2 SBC DIRDSP BCC DGTXIT STA TMP2 STX TMP1 INY BCS DGTLP2 ; DGTXIT TYA LDY DATBYT STA (FMSBPT),Y INY RTS ; ;*PARSE A FILE NAME WITH WILD ; CARD CHARACTERS ('*' AND '?') ; GETNM2 INY ; look for > in LDA (ICBALZ),Y ; the start CMP #'> ; of the fname BEQ GETNAM ; (for SpartaDOS ; ; Compatabiliy) DEY ; [Bob Puff] BNE GETNAM ; branch always ; GETFNM LDX CURFCB LDY # >361 LDA # <361 JSR SETDIR INY LDA (ICBALZ),Y INY CMP #': ; DEFAULT ; ; DIRECTORY? BNE GETNM2 ; IF NOT, CHECK ; ; FOR SPARTA ">" DEY STY TMP1 LDY DEFAULT STY ICDNOZ TYA STA ICDNO,X JSR SETUPD LDA CDIREC LDY CDIREC+1 JSR SETDIR LDY TMP1 ; GETNAM LDX #-11 INY AFTSTR LDA (ICBALZ),Y CMP #'* BNE TSTPER LDA #'? INY QLOOP STA FNAME+11-256,X INX BPL TOXITC ; END OF ; ; EXTENSION? PERFND CPX #-3 ; END OF FILE ; ; NAME? BNE QLOOP ; NO MORE -?-S BEQ AFTSTR ; TSTPER CMP #'. ; A PERIOD? BNE TSTCHR ; IF NOT, CHECK ; ; FOR INDIVIDUAL ; ; CHARACTERS LDA #' ; IF SO, FILL ; ; WITH SPACES INY BNE PERFND ; TSTCHR CMP #'? BCC ENDCHR ; IF < '?', ; ; CHECK FOR DIGIT CMP #'Z+1 ; ELSE, UPPER ; ; CASE LETTER, ; ; '?', OR '@'? BCC GOTCHR CMP #'_ BCC ENDCHR ; IF CARET, ; ; BACKSL. OR ; ; BRACKETS CMP #'z+1 ; LOWER CASE, ; ; ACCENT OR ; ; UNDERSCORE? BCC GOTCHR ENDCHR CPX #-11 ; IF FIRST CHAR, BEQ ERRCHR ; NO BYTES IN ; ; FILE NAME CMP #'0 ; ELSE, A DIGIT? BCC FILLNM ; IF NOT, THIS ; ; IS END OF NAME CMP #': BCS FILLNM ; GOTCHR STA FNAME+11-256,X INY INX BMI AFTSTR ; TOXITC LDA (ICBALZ),Y TSTDIR CMP #': ; LOOK FOR ; ; SUBDIRECTORY BEQ MYDIR ; IF MYDOS CMP #'> ; OR SPARTA BNE XITCHR ; IF FINISHED, ; ; RESTORE FCB PTR ; ; TO X AND EXIT MYDIR STY TMP2 JSR SFDIR ; ELSE, FIND ; ; FILE BCS FNER1 ; NO SUCH FILE JSR TONXDR BEQ FNER1 LDY TMP2 BNE GETNAM FNER1 LDA #174 ; RETURN ERROR ; ; DUP FNAME ERR .BYTE $2C ; FAKE BIT ; ERRCHR LDA #165 ; FILE NAME ERR JMP AEXIT ; FILLNM PHA LDA #' FILLLP STA FNAME+11-256,X INX BMI FILLLP PLA JMP TSTDIR ; ;*RETURN WITH NON-ZERO FLAG IF ; FILE IS A DIRECTORY ; TONXDR LDA #$10 ; FILE FOUND, A ; ; DIRECTORY? JSR GETFLAG BEQ TONXIT ; IF NOT, SET ; ; ZERO FLAG LDA DIRBUF+3,Y ; IF SO, MOVE ; ; POINTERS TO THE ; ; NEW LEVEL STA DIRBAS,X LDA DIRBUF+4,Y STA DIRBAS+1,X LDA #$10 ; AND CLEAR THE ; ; ZERO FLAG TONXIT RTS ; ;*ENTER A NAME INTO THE ; DIRECTORY AT DIRBUF[DIRDSP ; ENTNAME PHP LDX #-11 LDY DIRDSP NAMELP LDA FNAME+11-256,X ; LOAD ; ; THE MASK CHARACTER CMP #'? BNE STORIT ; IF NOT '?', ; ; SAVE IT AS IT ; ; APPEARS PLP PHP BCC NOSTOR ; IF CY CLEAR, ; ; LEAVE THE ; ; CHARACTERS UNCHANGED LDA #' ; IF CY SET, ; ; CONVERT '?'S TO ; ; SPACES STORIT STA DIRBUF+5,Y NOSTOR INY INX BMI NAMELP PLP LDY DIRDSP XITCHR LDX CURFCB RTS ; SFDIR JSR WBITMP ; INSURE BIT MAP ; ; IS SAFE LDX #255 STX HOLFN STX CURFNO INX STX DAUX2 INX STX DAUX1 LDX #READ STX DCOMND JSR SYSSET ; SET UP ; ; POINTERS FOR ; ; SYSTEM BUFFER I/O ; LDA ICDNOZ CMP RAMDKU BEQ CSFDIR ; IF RAMDISK, ; ; FORGET DENSITY ; ; CHECK LDX CURFCB ; IF A ROOT ; ; DIRECTORY ACCESS, ; ; READ BOOT SEC LDA DIRBAS,X ; IF IN A ; ; SUBDIRECTORY, ; ; ASSUME DENSITY ; ; IS OK CMP # <361 ; [Bob Puff] BNE CSFDIR ;;; lda DIRBAS+1,X ; Only ;;; ; occasionally ;;; ; will we get an ;;; ; extra read! ;;; cmp # >361 ;;; bne CSFDIR ; JSR DSKINV ; ELSE, READ THE ; ; FIRST BOOT SECTOR BMI ERRX JSR INVUNIT ; UPDATE DRIVE ; ; CONFIGURATION ; CSFDIR INC CURFNO ; READ NEXT ; ; 16-BYTE DIR ENTRY LDA CURFNO JSR BSECDS ; CONVERT TO ; ; SECTOR AND ; ; DISPLACEMENT XITCH1 BCS XITCHR BNE NOREAD ; IF DISP>0, ; ; PROCESS ENTRY JSR RDIRBK ; IF DISP=0, ; ; READ SECTOR ; NOREAD LDY DIRDSP LDA DIRBUF,Y BEQ FNDOLD ; ZERO IS END OF ; ; DIRECTORY (NO ; ; MORE ENTRIES) BMI FNDOLD ; NEGATIVE IS ; ; EMPTY SLOT ; ; (MAY HAVE MORE ; ; ENTRIES) ; ;*HANDLE DOS 2.5 FILES ; AND #$DF ; preserve lock ; ; flag CMP #3 ; is this DOS ; ; 2.5 + file? BNE NOD25 ; nope LDA #$41 ; otherwise, ; ; kludge the EOR DIRBUF,Y ; flag to make ; ; $42 STA DIRBUF,Y ; and save lock ; NOD25 AND #$01 ; IGNORE ANY ; ; FILE THAT IS ; ; MARKED "OPEN" BNE CSFDIR LDX #-11 CPNXCH LDA FNAME+11-256,X CMP #'? BEQ WCMTCH ; EVERYTHING ; ; MATCHES "?" CMP DIRBUF+5,Y BNE CSFDIR ; NO MATCH, LOOK ; ; AT THE NEXT ; ; DIRECTORY ENTRY WCMTCH INY INX BMI CPNXCH CLC BCC XITCHR ; ENTRY FOUND, ; ; RETURN WITH CY=0 ; FNDOLD LDX HOLFN BPL KPOLD ; IF AN EMPTY ; ; SLOT IS ALREADY ; ; FOUND, DO NOTHING LDX CURFNO STX HOLFN ; ELSE SAVE THIS ; ; ONE, ITS THE ; ; FIRST! KPOLD TAX BMI CSFDIR ; IF NOT END OF ; ; THE DIRECTORY, ; ; KEEP LOOKING ERRX SEC BCS XITCH1 ; ELSE, ENTRY ; ; NOT FOUND, ; ; RETURN WITH CY=1 ; ;*DOS I/O ROUTINES ; ;*DISK SECTOR I/O ROUTINES ; WRDISK SEC ; FMS DISK WRITE ; ; ENTRY RWDISK LDY FMSBPT ; DATA SECTOR ; ; READ/WRITE ENTRY LDA FMSBPT+1 JSR BUFSET LDA CURSEC+1,X LDY CURSEC,X FMDKIO PHP LDX DUNIT CPX RAMDKU BEQ RDKIO1 PLP PHA ; ALLOW FOR ; ; DENSITY CHANGE ; ; IN FORMAT, ETC. LDA SECSIZ-1,X ; [Bob Puff] TAX PLA JMP DKIO ; RDKIO1 JMP RDKIO ; ABSOLUTE DISK ; ; I/O ROUTINE WAS ; ; MOVED TO LOW RAM ; EXTEND JSR ALLOC LDA FCBOTC,X LSR A BCC REWRIT DEC FCBOTC,X JSR WTRICK JMP WRTTST ; REWRIT LDY LNKSEC+1,X LDA LNKSEC,X JSR SAVLNK WRTTST BMI RTBADF INC SECCNT,X BNE TONXT INC SECCNT+1,X ; TONXT LDA LNKSEC,X ; MAKE NEXT ; ; SECTOR STA CURSEC,X ; NEW CURRENT ; ; SECTOR LDA LNKSEC+1,X STA CURSEC+1,X LDA #0 STA LNKSEC,X ; ZERO LINK STA LNKSEC+1,X LENSET STA CURLEN,X ; ZERO CURRENT ; ; OFFSET LDA DLINK ; GET THE LINK STA MAXLEN,X ; NEW MAXLEN CLC ; CLEAR CY FOR ; ; LATER READ RTS ; RDNXTS LDA FCBFLG,X BEQ CHASE ; WRNXTS LDA FCBFLG,X BMI EXTEND ASL A BPL RDNXTS ASL A STA FCBFLG,X JSR WRDISK BPL RDNXTS ; RTBADF JMP HWERR ; RETURN HARDW ; ; ERROR CODE IF ; ; PRESENT ; SAVLNK PHA TYA LDY DLINK STA (FMSBPT),Y PLA INY STA (FMSBPT),Y INY LDA CURLEN,X NOBIT STA (FMSBPT),Y LDY FCBOTC,X BMI LEN16 ; 16-BIT LENGTH? LDA FCBFNO,X ASL A ASL A LDY DLINK ORA (FMSBPT),Y STA (FMSBPT),Y LEN16 JMP WRDISK ; WTRICK LDA LNKSEC,X STA SAVSEC,X LDA LNKSEC+1,X STA SAVSEC+1,X STX LSTIOCB LDA CURSEC,X STA LSTSEC LDA CURSEC+1,X STA LSTSEC+1 JMP WRDISK ; INSTRT JSR INITYP ; CHASE LDA LNKSEC,X ORA LNKSEC+1,X BEQ NOLINK JSR TONXT ; CY=0=READ JSR RWDISK BMI RTBADF ;CANNOT READ SO ; ; BAD FILE NUMBER ; ; (ERR=164) LDY DLINK LDA FCBOTC,X ; 16-BIT LINK? ORA #$7F BMI LNGLNK LDA (FMSBPT),Y LSR A LSR A CMP FCBFNO,X BNE XLINKED LDA #$03 LNGLNK AND (FMSBPT),Y STA LNKSEC+1,X INY LDA (FMSBPT),Y STA LNKSEC,X INY LDA (FMSBPT),Y STA MAXLEN,X DRDXIT CLC RTS ; XLINKED LDA ICCOM,X CMP #FMTCMD ; IS THIS A ; ; FORMAT? BNE FNOERR NOLINK SEC RTS ; ;*READ OR WRITE A DIRECTORY ; BLOCK ; RRDIR LDA FCBFNO,X ; SDIRBK STA CURFNO RDCFNO LDA CURFNO JSR BSECDS ; RDIRBK JSR WBITMP ; TAKE CONTROL ; ; OF SYSTEM BUFFER CLC .BYTE $A9 ; FAKE LDA $38 WDIRBK SEC RWDBK PHP LDX CURFCB ; PUT FCB # IN X STX DIUNIT ; SAVE THE DIR ; ; BUFFER IOCB JSR SYSSET CLC LDA DIRSEC ADC DIRBAS,X TAY LDA DIRBAS+1,X ADC #0 ; MULTIPLE DIRS ; ; REQ THIS [ChasM] PLP SYSRW JSR FMDKIO BPL DRDXIT LDA #163 ; BIT MAP R/W ; ; ERROR, RETURN ; ; SYSTEM ERR CODE .BYTE $AE ; FAKE LDX ; FNOERR LDA #164 ; BAD LINKS ERR STA DSTATS JMP HWERR ; FILE NUMBER ; ; MISMATCH ; ;*READ OR WRITE THE DISK VTOC ; (BIT MAP) ; RBITMP LDA CURMAP CMP ICDNOZ BEQ MAPXIT ; SKIP READ IF ; ; WHAT WE WANT ; ; IS ALREADY THERE JSR WBITMP ; ELSE, REAL ; ; I/O, SAVE CURRENT ; ; BUFFER CONTENTS ; LDA #0 TAY ZMAP STA MAPBUF,Y ; ZERO ENTIRE ; ; 512 STA MAPBUF+256,Y ;BYTES OF ; ; MAP BUFFFER DEY BNE ZMAP CLC JSR RWBMAP ; THEN READ 128 ; ; OR 256 BYTES OF ; ; VTOC DATA ; LDY #$FF STY DIUNIT ; INDICATE MAP ; ; (NOT DIR) IS LOADED STY MAP2 ; INDICATE ; ; SECOND PAGE OF ; ; MAP IS UNLOADED INY STY CHGMAP ; INDICATE MAP ; ; IS UNCHANGED INY STY MAP2MOD STY CURMP ; MAPCLR STA CURMAP ; AND SAVE DRIVE ; ; # MAP APPLIES TO MAPXIT RTS ; WBITMP LDA CHGMAP BEQ MAPCLR ; IF MAP NOT ; ; CHANGED, SKIP ; ; WRITING IT STA DUNIT FMTMAP LDA #0 STA CHGMAP ; ELSE MARK IT ; ; UNUSED STA CURMAP LDA DUNIT ; save drive # ; ; [Bob Puff] PHA SEC JSR RWBMAP PLA ; then restore ; ; it [Bob Puff] STA DUNIT ; WRNXTM LDA MAP2MOD BNE NOMPI2 ; IF THE PAGE ; ; BUFFER IS ; ; CLEAN, JUST EXIT LDA #$FF ; ELSE, WRITE IT ; ; TO DISK PHA LDA MAP2 INC MAP2MOD SEC BCS MUSTWM ; RDNXTM CMP MAP2 ; READ A PAGE ; ; INTO THE SECOND ; ; PAGE BUFFER BEQ NOMAPI ; IF IT IS ; ; ALREADY THERE, ; ; JUST EXIT PHA JSR WRNXTM ; ELSE, WRITE ; ; THE CURRENT ; ; PAGE (IF NECESSARY) PLA ; AND READ THE ; ; NEW ONE PHA CLC ; BY FALLING ; ; INTO MUSTWM ; ; WITH CY=0 ; MUSTWM PHA LDA # >MAPBUF+256 LDY # 360 PLP PHP JSR SYSRW ; READ OR WRITE ; ; THE FIRST SECTOR LDA MAPBUF CMP #3 ; IF DOS 2.0 ; ; DISK, READ ONE ; ; SECTOR BCC XITMBF ; EVEN IN SINGLE ; ; DENSITY JSR STEPBP DEY DDMAPX LDA # >360 PLP PHP JSR SYSRW ; READ OR WRITE ; ; THE SECOND (OR ; ; ONLY) SECTOR XITMBF PLP NOMPI2 LDA ICDNOZ STA DUNIT ; RESTORE THE ; ; USER DRIVE ; ; NUMBER TO DUNIT, RTS ; SINCE I/O MAY ; ; HAVE BEEN TO ; ; ANOTHER DRIVE ; SYSSET LDA # >MAPBUF LDY #