!   SDOSDISKVAL.PAS3
!
!       SDOSVALIDATE SECTION 1C
!       AT THIS POINT, WE KNOW THE BOOT.SYS IS OK,
!       AND THAT THAT DIRECTORY IS "OPENABLE".
!       WE MAY HAVE A BAD LSN TO ADD TO BADCLUSTERS.SYS
!       THIS PASS ALSO LETS USER MONKEY WITH NON-CRITICAL BOOT INFO
!
!
REM     7/21/80 MODIFIED FOR BASIC 1.4G
REM     1/30/81 MODIFIED FOR BASIC14H
!       12/23/82 MODIFIED FOR SDOS 1.1G
!       11/29/83 Fixed to unwriteprotect DIRECTORY.SYS
!       when updating. (RCW)

!
        PROGRAM ORIGIN :3600

        DATA ORIGIN :2E00

        COMMON Q$[34],DEVICE$[20],FNAME$[16],FNAME2$[16],OP$[12],DIR$[32]
        COMMON DIR2$[32],DEVDIR$[30]
        COMMON BYTE$[1],TWOB$[2],MINUS1$[2]
        COMMON NBPS,NLSN,NLCN,NSPC,HEADERBYTE,HCN,HCN2,HCIC,HCIC2
        COMMON MODF,MOD2F,DISMOUNT$[4],UNPROT$[4]
        COMMON NSPT,NTPC,NCYL,NOTBADS,NLCNS,NLCNS2,STAT$[23]
        COMMON SETMAP$[8],BUFFER$[20],BUFAD$[2]
        COMMON UNPROT2$[3]
        COMMON MAXFSIZE,GETPOS$[14],HCN$[2],HCIC$[1],LCNS$[2],FSIZE$[4]
        COMMON PROT$[1],EMPTY$[6],PROT,FSIZE,CKSUM,BYTES,BAD,KILL,POS
        COMMON AZ$[27]
        COMMON PER09$[11]
        COMMON OPTIONS

REM     COMMON BETWEEN SDOSVALIDATE 1 AND SDOSVALIDATE 3
        COMMON BADLSN$[3],DIRLSN

        COMMON UPDATEBOOT/0/,FFFFFF$[3]
        COMMON FFFF$[2],ERTYPE

        DIM BOOT$(512)
        DIM CCSETFILEPROT$/:E,8,0,:11/,WBPROTECT$/:41/,NOPROTECT$/0/
!^L
! *** MAIN PROGRAM ***
        DEF MSB(X1)=INT(X1/256)
        DEF LSB(X2)=INT(X2-256*MSB(X2))

        PRINT   "(300) SDOSDISKVALIDATE pass 3 V1.1h"
        LET LEN(BOOT$)=NBPS
        OPEN #1,DEVICE$
            READ #1@0,BOOT$[1,NBPS]
        CALL SYSCALL(DISMOUNT$)
        CLOSE #1
        OPEN #2,DEVICE$
        BUFFER$=BOOT$[23,2]
        CALL SYSCALL(SETMAP$,BUFFER$)
        IF OPTIONS=0 THEN 171
        PRINT "(301) BOOT:DISKID = ";BOOT$[33,32]
        IF OPTIONS<>2 THEN 16
195     INPUT "(302) New BOOT:DISKID (default is no change): " Q$
        IF      Q$="" THEN 16
        FOR I=LEN(Q$)+1 TO 33
        Q$[I]=ASC(" ")
        NEXT I
        FOR     I=1 TO LEN(Q$)
        IF      Q$(I,1)='"' THEN
                PRINT   '(303) Double quotes (") are not allowed in BOOT:DISKID.'
                GOTO    195
        FI
        NEXT    I
        IF      LEN(Q$)>32 THEN
                PRINT   "(317) Length of BOOT:DISKID must be at most 32 characters."
                GOTO    195
        FI
        LEN(Q$)=32\BOOT$[33,32]=Q$
        UPDATEBOOT=1
16      PRINT "(304) BOOT:MINALLOC=";BOOT$[19]*256+BOOT$[20]
        PRINT "      BOOT:MIDALLOC=";BOOT$[21]*256+BOOT$[22]
        IF OPTIONS<>2 THEN 17
165     INPUT "(305) Change BOOT:MINALLOC or BOOT:MIDALLOC (default=NO)? " Q$
        GOSUB 1000\ON INVALIDANSWER GOTO 165
        IF Q$<>"Y" THEN 17
        INPUT "(306) Enter new value for BOOT:MINALLOC (default is no change): " Q$
        IF Q$="" THEN 18
        BOOT$[19]=MSB(VAL(Q$))
        BOOT$[20]=LSB(VAL(Q$))
        UPDATEBOOT=1
18      INPUT "(307) Enter new value for BOOT::MIDALLOC (default is no change): " Q$
        IF Q$="" THEN 17
        BOOT$[21]=MSB(VAL(Q$))
        BOOT$[22]=LSB(VAL(Q$))
        UPDATEBOOT=1
17      OP$=HEX$(BOOT$[:1A])
        DIR$=OP$[4,2] CAT "/"
        OP$=HEX$(BOOT$[:19])
        DIR$=DIR$ CAT OP$[4,2] CAT "/"
        OP$=HEX$(BOOT$[:1B])
        DIR$=DIR$ CAT OP$[4,2]
        PRINT "(308) BOOT:CREATIONDATE = ";DIR$
        IF OPTIONS<>2 THEN 172
        INPUT "(309) Enter new BOOT:CREATIONDATE (default is no change): " Q$
        IF Q$="" THEN 172
        X=FIND(Q$,"/")
        IF X=0 THEN 17
        DIR$[1]=VAL(":" CAT Q$[1,X-1])
        Q$=RIGHT$(Q$,X+1)
        X=FIND(Q$,"/")
        IF X=0 THEN 17
        DIR$[2]=VAL(":" CAT Q$[1,X-1])
        Q$=RIGHT$(Q$,X+1)
        DIR$[3]=VAL(":" CAT Q$)
        BOOT$[:1A]=DIR$[1]
        BOOT$[:19]=DIR$[2]
        BOOT$[:1B]=DIR$[3]
        UPDATEBOOT=1
172     IF UPDATEBOOT=0 THEN 171
        INPUT "(310) Update Boot Sector? " Q$
        GOSUB 1000\ON INVALIDANSWER GOTO 17
        IF Q$="N" THEN 171
        PRINT "(318) Updating Boot Sector."
        RESTORE #2,0
        CALL SYSCALL(UNPROT2$)
        GOSUB 600
        BOOT$[32]=CKSUM
        WRITE #2,BOOT$[1,NBPS]
171     CLOSE #2
        IF BADLSN$=FFFFFF$ THEN 180
        PRINT   "(316) Last bad Logical Sector number on ";DEVICE$;" is :";
        FOR ZZ=1 TO 3 DO PRINT HEX$(BADLSN$(ZZ))(4,2);
        PRINT
        OPEN #1,DEVICE$ CAT "DIRECTORY.SYS"
        SYSCALL #1,CCSETFILEPROT$,NOPROTECT$
        OPEN #2,DEVICE$
175     READ #1,FNAME$,FNAME2$
        IF EOF(1) THEN ...
&       PRINT "(311) A new bad LSN exists, but BADCLUSTERS.SYS doesn't!"\GOTO 179
        IF FNAME2$[3]=0 THEN 175
        IF FNAME$<>"BADCLUSTERS.SYS " THEN 175
        IF NBPS*NSPC=FNAME2$[4]**8+FNAME2$[5] THEN ...
&       PRINT "(312) BADCLUSTERS.SYS has no room to record new bad cluster!"\GOTO 179
        RESTORE #2,(FNAME2$[1]**8+FNAME2$[2])*NSPC*NBPS
        POS=(FNAME2$[1]**8+FNAME2$[2])*NSPC*NBPS
        I=(BADLSN$[1]**8+BADLSN$[2])*256+BADLSN$[3]
        I=INT(I/NSPC)
176     READ #2,HCN$\POS=POS+2
        IF HCN$[1]**8+HCN$[2]=I THEN
                PRINT "(313) Bad Cluster ";HEX$(I);" is already in BADCLUSTERS.SYS!"
                GOTO 179
        FI
        IF HCN$<>FFFF$ THEN 176
        RESTORE #2,POS-2
        HCN$[1]=MSB(I)\HCN$[2]=LSB(I)
        CALL SYSCALL(UNPROT2$)
        WRITE #2,HCN$
        PRINT "(314) LCN ";HEX$(I);" has been added to BADCLUSTERS.SYS"
        PRINT "      This will probably cause Pass 4 to find that BADCLUSTERS.SYS"
        PRINT "      overlaps some other file."
        CALL SYSCALL(GETPOS$,'',BUFFER$)
        POS=(BUFFER$[1]**8+BUFFER$[2])*256^2+(BUFFER$[3]**8+BUFFER$[4])-16
        RESTORE #1,POS
        I=FNAME2$[4]**8+FNAME2$[5]+1
        IF (I-NBPS*INT(I/NBPS))<>0 THEN 177
        LET FNAME2$[3]=1+FNAME2$[3]\! INC HCSIC
        FOR J=2 TO NBPS/2 \! FILL IN THE NEW HEADER SECTOR
                WRITE #2,FFFF$
        NEXT J
177     FNAME2$[4]=MSB(I)\FNAME2$[5]=LSB(I)
        WRITE #1,FNAME2$
179     SYSCALL #1, CCSETFILEPROT$,WBPROTECT$
        CLOSE #1
        CLOSE #2

180     PRINT "(315) Chaining to SDOSDISKVAL.PAS4"
        CHAIN "SDOSDISKVAL.PAS4"


600     CKSUM=0
        FOR I=17 TO 31
        CKSUM=CKSUM+BOOT$[I]
        NEXT I
        CKSUM=:FF XOR (CKSUM&:FF)
        RETURN


1000    ! IS THAT A GOOD RESPONSE????
        IF Q$=""
        THEN
                INVALIDANSWER=0
                RETURN
        ELSE
                LET Q$=UPPERCASE$(Q$)[1,1] \  REM DON'T CARE ABOUT "ES" OR "O" OR ....
                LET INVALIDANSWER=Q$<>"N" AND Q$<>"Y"
                RETURN
        FI

        END
END
