;TITLE: SFA16.ASM - SET FILE ATTRIBUTE PROGRAM VERSION 16 ; ;BY: Robert Wilcox ; 920 N. Washington ; Owosso, MI 48867 ; (517) 725-8531 ; VERS EQU 16 ;version 1.6 ; ;This program was originally written to set files FOR or NOT FOR distribution ;via MODEM programs by setting the MSB of the first character of the file ;name high to make the file NOT FOR DISTRIBUTION. ; ;Later it was modified to also set the R/W-R/O and DIR-SYS attributes. ; ;-------------------------------------------------------------------------- ; MODIFICATIONS : ;-------------------------------------------------------------------------- ;1.1 4/14/83 Option (FOR or NOT) may be given in the command line: ; ; SFA filename.typ F ; or ; SFA filename.typ N ; ; If the option is not given in the command line, it will ; be prompted for. The option may be in upper or lower ; case. ; ;1.2 4/18/83 Fixed so that present file attributes (R/O, SYS) are ; not affected. ; ;1.3 5/13/83 Added password. ; ;1.4 10/1/83 Password no longer echoed to screen. ; ;1.5 11/27/83 Ambiguous file names allowed ; ;1.6 11/30/83 Can optionally set or reset R/O and DIR attributes as ; well as distribution attribute. ; ;-------------------------------------------------------------------------- ; NO EQU 0 YES EQU NOT NO ; PASSW EQU YES ;YES - PASSWORD REQUIRED ; ORG 0100H BDOS EQU 5 DFCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK SECFN EQU 6CH ;SECOND FILE NAME IN COMMAND LINE CR EQU 13 ;CARRIAGE RETURN LF EQU 10 ;LINE FEED EOS EQU '$' ;END OF STRING FLAG ; BEGIN: JMP BEGIN1 NAME: DB CR,LF,'SFA - VERS ' DB VERS/10 + '0','.',VERS MOD 10 + '0',CR,LF,EOS BEGIN1: LXI H,0 DAD SP SHLD OLDSTK LXI SP,STACK LXI H,TABLE SHLD POINTER ;INITIALIZE TABLE POINTER XRA A STA FCOUNT ;....AND FILE COUNTER LXI D,NAME CALL WASC LDA DFCB+1 CPI ' ' JNZ TRY LXI D,HLPMSG JMP EXIT ; TRY: ; IF PASSW MVI A,14 ;ELSE SET UP OUT 130 ;PORT FOR MODEM DETECT IN 131 ;AND SEE IF ON-LINE ANI 2 ;BIT 2 = MODEM ON-LINE STATUS JNZ DOIT ;IF BIT=1 ITS LOCAL, SO GO AHEAD, ;ELSE GET PASSWORD... LXI D,PWMSG ;PRINT 'ENTER PASSWORD' CALL WASC CALL ANSW ;GET PASSWORD FROM USER CALL COMPAR ;COMPARE ANSWER TO PASSWORD JZ DOIT ;CONTINUE IF ANSWER CHECKS LXI H,COUNT ;OTHERWISE DECREMENT COUNT DCR M ;AND ABORT IF JZ ABORT ;ALLOTTED TRIES ARE USED UP JMP TRY ;OTHERWISE TRY AGAIN. ENDIF ; DOIT: LXI H,SECFN+1 MOV A,M SUI ' ' JZ NOATRQ ;IF NO ATTRIBUTE REQUEST ON COMMAND LINE LXI D,ATSTOR ;ELSE MOVE ATTRIBUTES REQUESTED MVI B,3 ;TO STORAGE CALL MOVE ;AREA MVI A,1 ;AND FLAG THAT WE DID IT NOATRQ: STA ATRQFG LXI D,DFCB CALL SRCHF INR A LXI D,FNFMSG JZ EXIT ; PUSH PSW LXI D,BEGMSG CALL WASC POP PSW JMP CONT1 ; DOITAGN: LXI D,DFCB CALL SRCHN ;SEARCH FOR NEXT MATCH INR A JZ CONT2 ;NO MORE FILE MATCHES ; CONT1: DCR A ;RESTORE DIRECTORY POINTER ANI 3 MOV L,A MVI H,0 DAD H DAD H DAD H DAD H DAD H LXI D,81H ;POINT TO 1ST CHAR OF FNAME DAD D XCHG ;DE=DIR. ADDR. MVI B,15 ;# BYTES TO MOVE LHLD POINTER ;HL=TABLE ADDRESS MLOOP: LDAX D ;GET FILE NAME BYTE MOV M,A ;PUT IN TABLE INX H INX D DCR B JNZ MLOOP SHLD POINTER LXI H,FCOUNT INR M ;INCREMENT FILE COUNTER JMP DOITAGN ; ; CONT2: LXI H,TABLE SHLD POINTER CONT3: LDA FCOUNT ORA A JZ DONE CALL PRTFN ;PRINT FILENAME CALL MVNAME ;MOVE NAME TO DFCB LDA ATRQFG ANA A JZ ASK1 LXI H,ATSTOR MOV A,M JMP CKOPT1 ASK1: LXI D,QUERY1 ;GET FOR/NOT OPTION FROM CONSOLE CALL WASC CALL CONIN CALL UPCASE PUSH PSW MVI B,LNQRY1 CALL ERASE POP PSW ; CKOPT1: ;CHECK OPTION, F, N, Q CPI ' ' ;SPACE TO GET NEXT FILE JZ NXTFIL CPI 'Q' ;"Q" TO QUIT JZ EXITNM ;EXIT NO MESSAGE CPI '-' ; - FOR NO CHANGE JZ NEXT1 CPI 'N' JZ SETNOT CPI 'F' JNZ ASK1 ; SETFOR: LDA DFCB+1 ANI 07FH STA DFCB+1 CALL SFA LXI D,SFDMSG JMP SETRET1 ; SETNOT: LDA DFCB+1 ORI 80H STA DFCB+1 CALL SFA LXI D,NFDMSG SETRET1: CALL WASC NEXT1: LDA ATRQFG ANA A JZ ASK2 INX H MOV A,M JMP CKOPT2 ASK2: LXI D,QUERY2 ;GET R/W-R/O OPTION FROM CONSOLE CALL WASC CALL CONIN CALL UPCASE PUSH PSW MVI B,LNQRY2 CALL ERASE POP PSW ; CKOPT2: ;CHECK OPTION, W, O, Q CPI ' ' ;SPACE TO GET NEXT FILE JZ NXTFIL CPI 'Q' ;"Q" TO QUIT JZ EXITNM ;EXIT NO MESSAGE CPI '-' ; - FOR NO CHANGE JZ NEXT2 CPI 'O' JZ RDONLY CPI 'W' JNZ ASK2 ; RDWRT: LDA DFCB+9 ANI 07FH STA DFCB+9 CALL SFA LXI D,SRWMSG JMP SETRET2 ; RDONLY: LDA DFCB+9 ORI 80H STA DFCB+9 CALL SFA LXI D,SROMSG SETRET2: CALL WASC NEXT2: LDA ATRQFG ANA A JZ ASK3 INX H MOV A,M JMP CKOPT3 ASK3: LXI D,QUERY3 ;GET SYS/DIR OPTION FROM CONSOLE CALL WASC CALL CONIN CALL UPCASE PUSH PSW MVI B,LNQRY3 CALL ERASE POP PSW ; CKOPT3: ;CHECK OPTION, S, D, Q CPI ' ' ;SPACE TO GET NEXT FILE JZ NXTFIL CPI 'Q' ;"Q" TO QUIT JZ EXITNM ;EXIT NO MESSAGE CPI '-' ; - FOR NO CHANGE JZ NXTFIL CPI 'S' JZ SETSYS CPI 'D' JNZ ASK3 ; SETDIR: LDA DFCB+10 ANI 07FH STA DFCB+10 CALL SFA LXI D,DIRMSG JMP SETRET3 ; SETSYS: LDA DFCB+10 ORI 80H STA DFCB+10 CALL SFA LXI D,SYSMSG SETRET3: CALL WASC NXTFIL: LHLD POINTER LXI D,15 ;SET POINTER TO NEXT DAD D ;FILE NAME SHLD POINTER LXI H,FCOUNT ;DECREMENT FILE COUNTER DCR M MVI C,11 ;GET CONS. STATUS CALL BDOS ;CHECK FOR ABORT REQUEST ANA A JZ CONT3 ;CONTINUE IF NO KEY STRUCK LXI D,ABORTM ;ELSE PRINT ABORT MESSAGE JMP EXIT ;AND RETURN TO CP/M. ; ;SEARCH FOR FIRST OCCURRENCE OF FILE ;ON ENTRY DE POINTS TO FCB ; SRCHF: PUSH H PUSH D PUSH B MVI C,17 CALL BDOS POP B POP D POP H RET ; ;SEARCH FOR NEXT OCCURRENCE OF FILE ;ON ENTRY DE POINTS TO FCB ; SRCHN: PUSH H PUSH D PUSH B MVI C,18 CALL BDOS POP B POP D POP H RET ; ;SET FILE ATTRIBUTES SFA: PUSH H PUSH D PUSH B LXI D,DFCB MVI C,30 CALL BDOS POP B POP D POP H RET ; ;WEOLC - WRITE END OF LINE (CR,LF) ; WEOLC: MVI A,CR CALL WACC MVI A,LF JMP WACC ; ; ;convert character in A to upper case UPCASE: CPI 'a' RC CPI 'z'+1 RNC ANI 5FH ;MAKE UPPER CASE RET ; ;PRINT FILE NAME PRTFN: CALL WEOLC MVI B,11 LHLD POINTER PRTFN1: MOV A,M CPI ' ' CNZ WACC INX H MOV A,B CPI 4 JNZ PRTFN2 MVI A,'.' CALL WACC PRTFN2: DCR B JNZ PRTFN1 RET ; ERASE: ;BACKS UP AND ERASES # OF CHAR'S IN B REG MVI C,' ' ;SPACE MVI D,8 ;BACKSP ERALP: MOV A,D ! CALL WACC MOV A,C ! CALL WACC MOV A,D ! CALL WACC DCR B JNZ ERALP RET ; ;WRITE CONSOLE CHARACTER ;ENTRY: CHARACTER IN ACCUM. ; WACC: PUSH H PUSH D PUSH B MOV E,A MVI C,2 CALL BDOS POP B POP D POP H RET ; ; WASC: PUSH H PUSH D PUSH B MVI C,9 CALL BDOS POP B POP D POP H RET ; CONIN: PUSH H PUSH D PUSH B MVI C,1 CALL BDOS POP B POP D POP H RET ; DONE: LXI D,BYEMSG EXIT: CALL WASC EXITNM: LHLD OLDSTK SPHL RET ; ;MOVE FILENAME TO DFCB MVNAME: LHLD POINTER LXI D,DFCB + 1 ;LEAVE DRIVE BYTE ALONE MVI B,15 ; MOVE: MOV A,M STAX D INX H INX D DCR B JNZ MOVE RET ; ; IF PASSW ;GET ANSWER FROM CONSOLE ROUTINE ANSW: LXI H,ANSBUF+1 MVI B,0 ;COUNTER ANSWLP: INX H ;STORE 1ST CHAR AT ANSBUF+2 PUSH H PUSH B CHRIN: MVI C,6 ;READ CONSOLE DIRECT (NO ECHO) MVI E,0FFH CALL BDOS CPI 0 JZ CHRIN POP B POP H CALL UPCASE CPI CR JZ ANSXIT MOV M,A INR B ;COUNT 1 CHAR. LDA ANSBUF CMP B JNZ ANSWLP ANSXIT: MOV A,B STA ANSBUF+1 RET ; ;******************************************************************** ; COMPARE SUBROUTINE ;RETURNS Z FLAG=0 IF GOOD COMPARE, 1 IF NOT ;******************************************************************** COMPAR: LXI H,PASWRD ;POINT TO PASSWORD STRING COMPR1: LXI D,ANSBUF+1 ;POINT TO ANSWER BUFFER LDAX D MOV B,A ;B HAS # CHAR'S ENTERED MOV A,M ;A HAS LENGTH OF PASSWORD MOV C,A ;C HAS LENGTH OF PASSWORD CMP B ;IF NOT SAME, DON'T BOTHER TO COMPARE JNZ NXTWRD CLOOP: INX D ;POINT TO NEXT CHARACTER INX H LDAX D ;CHAR FROM ANSWER TO A CMP M ;SAME? JNZ NXTWD1 ;TRY NEXT PASSWORD IF NOT DCR C DCR B ;MORE CHARACTERS IN INPUT BUFFER? JNZ CLOOP ;YES - KEEP ON CHECKING RET ;NO MORE..WE HAVE A GOOD COMPARE ; NXTWRD: INX H ;MOVE POINTER TO NXTWD1: INX H ;NEXT PASSWORD IN DCR C ;THE TABLE JNZ NXTWD1 MOV A,M ;GET LENGTH BYTE OR END FLAG ANA A ;IF NOT END OF PASSWORD TABLE JNZ COMPR1 ;RESET ANSWER POINTER ;AND TRY NEXT PASSWORD DCR A ;OTHERWISE MAKE NON-ZERO RET ;AND RETURN TO TRY ROUTINE ; ABORT: LXI D,NAVMSG ;PRINT 'FUNCTION NOT AVAILABLE' JMP EXIT ;AND RETURN TO CP/M PWMSG: DB CR,LF,'ENTER PASSWORD: $' NAVMSG: DB CR,LF,'Sorry, SFA function not available$' ; ANSBUF: DB 20 DS 22 PASWRD: DB PSWRD1-PASWRD-1,'MICROSYSTEMS ARE FUN' PSWRD1: DB PSWRD2-PSWRD1-1,'APOTAKR' PSWRD2: DB PSWRDE-PSWRD2-1,'SCHUTZMARKE' PSWRDE: DB 0 ;END OF TABLE FLAG COUNT: DB 3 ;ALLOW 3 TRIES ENDIF ; QUERY1: DB ' ++ For or Not (F/N) ? ',EOS LNQRY1: EQU $ - QUERY1 QUERY2: DB ' ++ r/Write or r/Only (W/O) ? ',EOS LNQRY2: EQU $ - QUERY2 QUERY3: DB ' ++ Sys or Dir (S/D) ? ',EOS LNQRY3: EQU $ - QUERY3 BEGMSG: DB CR,LF,'At prompt, press spacebar to advance to next file,' DB CR,LF,'''-'' to advance to next attribute, or ''Q'' to Quit.' DB CR,LF,LF,'Press any key to abort in automatic mode.',CR,LF,EOS HLPMSG: DB CR,LF DB 'To set file attributes (distribution, R/O, DIR-SYS)',CR,LF,LF DB 'Use: SFA afn [A][B][C]',CR,LF,LF DB 'Where A, B and C represent the requested attribute(s)' DB CR,LF,LF DB 'A: F - FOR distribution or N - NOT for distribution',CR,LF DB 'B: W - read/Write or O - read Only',CR,LF DB 'C: D - DIRectory file or S - SYStem file',CR,LF,LF DB 'Zero thru three attributes may be specified.',CR,LF DB 'X in any position will cause that attribute to be ' DB 'prompted for',CR,LF DB 'and ''-'' skips that attribute. I.E.,',CR,LF,LF DB ' SFA *.* fx-',CR,LF,LF DB 'sets each file FOR distribution, prompts for RO/RW,',CR,LF DB 'and skips SYS/DIR.',CR,LF DB 'Pressing any key aborts SFA.',CR,LF DB CR,LF,EOS ; FNFMSG: DB CR,LF,'File not found',EOS ABORTM: DB CR,LF,'SFA aborted',eos BYEMSG: DB CR,LF,'Done',eos ; SRWMSG: DB ', R/W',EOS SROMSG: DB ', R/O',EOS DIRMSG: DB ', DIR',EOS SYSMSG: DB ', SYS',EOS SFDMSG: DB ' FOR dist.',EOS NFDMSG: DB ' NOT for dist.',EOS TFCB: DS 16 ;TEMP FCB ATRQFG: DB 0 ;ATTRIBUTE REQUESTED FLAG 1=YES, 0=NO FCOUNT: DB 0 ;FILE COUNTER ATSTOR: DS 3 ;STORAGE FOR ATTRIBUTES REQUESTED POINTER DW TABLE OLDSTK: DW 0 DS 64 STACK: EQU $ ; TABLE: DB 0 ; END BEGIN