; PROGRAM: PROTECT ; VERSION: 2.0 ; DATE: 16 Jan 83 ; AUTHOR: RICHARD CONN ; PREVIOUS VERSIONS: 1.3 (6 Jan 83), 1.2 (7 Dec 82), 1.1 (10 NOV 82) ; PREVIOUS VERSION: PROTECT.ASM Version 1.0 (26 OCT 81) VERS equ 20 ; ; This program is Copyright (c) 1982, 1983 by Richard Conn ; All Rights Reserved ; ; ZCPR2 and its utilities, including this one, are released ; to the public domain. Anyone who wishes to USE them may do so with ; no strings attached. The author assumes no responsibility or ; liability for the use of ZCPR2 and its utilities. ; ; The author, Richard Conn, has sole rights to this program. ; ZCPR2 and its utilities may not be sold without the express, ; written permission of the author. ; ; ; PROTECT Command -- ; PROTECT is used to set the file protection and tag attribute bits ; for CP/M 2.x files in the ZCPR2 environment. It is invoked via command ; lines of the following forms: ; PROTECT dir:afn1,dir:afn2,... keys <-- Set unconditionally ; PROTECT dir:afn1,... keys I <-- Inspect Mode ; PROTECT dir:afn1,... C <-- Set each ufn ; ; In the above examples, the reference 'keys' is a string of zero or ; more characters which may be any of the following: ; ; A <-- Set AR Attribute ; R <-- Set R/O Attribute (no R sets R/W) ; S <-- Set SYS Attribute (no S sets Non-System) ; n <-- Set Tag Attribute (1 <= n <= 8) ; ; Examples: ; PROTECT *.COM RS <-- Sets all COM files to R/O SYStem ; PROTECT *.COM RSI <-- Same, with user approval ; PROTECT *.COM C <-- Allows user to specify for each ; PROTECT MYPROG.COM 1R <-- Sets Tag Bit 1 and R/O Attribute ; FALSE EQU 0 TRUE EQU NOT FALSE ESIZE EQU 16 ; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE) EXT DIRF ; DIRECTORY PROCESSOR EXT ZGPINS ; INIT BUFFERS EXT ZFNAME ; FILE NAME PROCESSOR EXT BBLINE ; INPUT LINE EDITOR EXT INITFCB ; INIT FCB EXT BDOS ; BDOS ENTRY EXT RETUD ; RETURN CURRENT USER/DISK EXT PUTUD ; SAVE CURRENT USER/DISK EXT GETUD ; RESTORE CURRENT USER/DISK EXT MOVEB ; COPY ROUTINE EXT PHLDC ; PRINT HL AS DECIMAL CHARS EXT PRINT ; PRINT ROUTINE EXT COUT ; CONSOLE OUTPUT ROUTINE EXT CIN ; CONSOLE INPUT ROUTINE EXT CAPS ; CAPITALIZE ROUTINE EXT CRLF ; NEW LINE ROUTINE EXT FILLB ; FILL ROUTINE EXT CODEND ; CODE END COMPUTATION ROUTINE ; ; CP/M EQUATES ; CPM EQU 0 ; WARM BOOT FCB EQU 5CH ; FCB BUFF EQU 80H ; INPUT LINE BUFFER CR EQU 13 ; LF EQU 10 ; ; ; Branch to Start of Program ; JMP START ; ;****************************************************************** ; ; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format ; ; This data block precisely defines the data format for ; initial features of a ZCPR2 system which are required for proper ; initialization of the ZCPR2-Specific Routines in SYSLIB. ; ; ; EXTERNAL PATH DATA ; EPAVAIL: DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES) EPADR: DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE ; ; INTERNAL PATH DATA ; INTPATH: DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT ; DISK = 1 FOR A, '$' FOR CURRENT ; USER = NUMBER, '$' FOR CURRENT DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT DB 0 ; END OF PATH ; ; MULTIPLE COMMAND LINE BUFFER DATA ; MCAVAIL: DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE? MCADR: DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE ; ; DISK/USER LIMITS ; MDISK: DB 4 ; MAXIMUM NUMBER OF DISKS MUSER: DB 31 ; MAXIMUM USER NUMBER ; ; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK ; DOK: DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES) UOK: DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES) ; ; PRIVILEGED USER DATA ; PUSER: DB 10 ; BEGINNING OF PRIVILEGED USER AREAS PPASS: DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL ; ; CURRENT USER/DISK INDICATOR ; CINDIC: DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS) ; ; DMA ADDRESS FOR DISK TRANSFERS ; DMADR: DW 80H ; TBUFF AREA ; ; NAMED DIRECTORY INFORMATION ; NDRADR: DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY NDNAMES: DB 64 ; MAX NUMBER OF DIRECTORY NAMES DNFILE: DB 'NAMES ' ; NAME OF DISK NAME FILE DB 'DIR' ; TYPE OF DISK NAME FILE ; ; REQUIREMENTS FLAGS ; EPREQD: DB 0FFH ; EXTERNAL PATH? MCREQD: DB 0FFH ; MULTIPLE COMMAND LINE? MXREQD: DB 0FFH ; MAX USER/DISK? UDREQD: DB 0FFH ; ALLOW USER/DISK CHANGE? PUREQD: DB 0FFH ; PRIVILEGED USER? CDREQD: DB 0FFH ; CURRENT INDIC AND DMA? NDREQD: DB 0FFH ; NAMED DIRECTORIES? Z2CLASS: DB 0 ; CLASS 0 DB 'ZCPR2' DS 10 ; RESERVED ; ; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA ; ;****************************************************************** ; ; ; Start of Program ; START: LXI H,0 ; GET STACK PTR DAD SP SHLD STACK ; SAVE IT LXI SP,STACK ; SET SP CALL PUTUD ; SAVE CURRENT USER/DISK AWAY MVI A,0FFH ; SET DEFAULT USER STA USER CALL ZGPINS ; INIT BUFFERS CALL PRINT DB 'PROTECT Version ' DB VERS/10+'0','.',(VERS MOD 10)+'0',0 LDA FCB+1 ; GET FIRST CHAR OF FILE NAME CPI ' ' ; NO FILE SPEC? JZ HELP CPI '/' ; OPTION CAUGHT? JNZ ECONT ; PRINT HELP INFORMATION HELP: CALL PRINT DB CR,LF,'PROTECT Command --' DB CR,LF,' PROTECT dir:filename.typ,dir:fn.ft,dir:fn.ft,... ooo' DB CR,LF,LF,'d is disk, u is user, and o is one or more option ' DB 'letters.' DB CR,LF,'If one or more options are specified, the o MUST be ' DB 'preceded by a space.' DB CR,LF,'Nothing is required, and wild cards (?,*) are ' DB CR,LF,'permitted. o is optional, and valid options are -' DB CR,LF,' C -- Control Mode (Allow user to set each file)' DB CR,LF,' I -- Inspect Mode (Give user option to set att)' DB CR,LF,' n -- 1 <= n <= 8; Set Tag Attribute' DB CR,LF,' A -- Set AR (Archive) Attribute' DB CR,LF,' R -- Set R/O Attribute (no R sets R/W)' DB CR,LF,' S -- Set SYS Attribute (no S sets Non-System)' DB CR,LF,'dir: is a named directory or the form du:.' DB CR,LF,'Named Directories are ',0 LDA NDREQD ; NAMES REQUIRED? ORA A ; 0=NO JNZ HELP1 CALL PRINT DB 'NOT ',0 HELP1: CALL PRINT DB 'Permitted in this Version of PROTECT' DB CR,LF,'If u is omitted, current user is assumed, as with d.' DB CR,LF,LF,'Special forms are:' DB CR,LF,' PROTECT dir: <-- Prot all files in named directory' DB CR,LF,' PROTECT du: <-- Prot all files in disk d, user u' DB CR,LF,' PROTECT u: <-- Prot all files in user u on ' DB 'current disk' DB CR,LF,' PROTECT d: <-- Prot all files on disk d in ' DB 'current user' DB 0 ; RETURN TO OS RETURN: LHLD STACK ; GET OLD STACK SPHL ; SET IT RET ; USER CHANGE NOT ALLOWED ERROR UNOK: CALL PRINT DB CR,LF,'User Number Change Not Allowed -- Aborting',0 JMP RETURN ; DISK CHANGE NOT ALLOWED ERROR DNOK: CALL PRINT DB CR,LF,'Disk Change Not Allowed -- Aborting',0 JMP RETURN ; PLACE ZERO AT END OF BUFFER ECONT: LXI H,BUFF ; PT TO BUFFER MOV A,M ; GET COUNT INX H ; PT TO FIRST CHAR ADD L ; PT TO END OF BUFFER MOV L,A MOV A,H ACI 0 MOV H,A MVI M,0 ; COPY BUFFER INTO TEMP BUFFER LXI H,BUFF ; PT TO BUFFER MOV B,M ; GET CHAR COUNT INX H ; PT TO FIRST CHAR INR B ; ADD ENDING 0 LXI D,CMDLNE ; PT TO CMDLNE BUFFER CALL MOVEB ; COPY INTO COMMAND LINE BUFFER ; EXTRACT FLAGS IF PRESENT XRA A ; SET NO INSPECT, NO R/O, NO ARCH, AND NO SYSTEM FILES STA INSPECT STA READONLY STA SYSTEM STA ARCHIVE STA CONTROL ; SET NO CONTROL MODE MVI B,8 ; CLEAR TAG BITS LXI H,TAGS CALL FILLB LXI H,0 ; SET FILE COUNT SHLD FILECNT LXI H,CMDLNE ; PT TO BUFFER ; SKIP TO FILE NAME STRING SBLANK: MOV A,M ; SKIP TO NON-BLANK CPI ' ' ; ? JNZ SBL1 INX H ; PT TO NEXT CHAR JMP SBLANK ; SKIP TO END OF FILE NAME STRING SBL1: MOV A,M ; SKIP TO OR EOL ORA A ; DONE? JZ OPT CPI ' ' ; JZ OPT INX H ; PT TO NEXT JMP SBL1 ; CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO OPT: CPI '/' ; OPTION CHAR? JNZ OPTION INX H ; SKIP SLASH ; PROCESS LIST OF OPTIONS OPTION: MOV A,M ; GET BYTE ORA A ; DONE? JZ DSPEC INX H ; PT TO NEXT CHAR CPI ' ' ; SKIP OVER SPACES JZ OPTION CPI '/' ; IF OPTION LETTER, OBVIOUS ERROR, SO HELP JZ HELP CPI '1' ; DIGIT? JC HELP CPI '8'+1 ; IN RANGE? JC OPTNUM CPI 'C' ; CONTROL? JZ OPTCTRL CPI 'I' ; INSPECT? JZ OPTINS CPI 'A' ; ARCHIVE JZ OPTAR CPI 'R' ; READ/ONLY? JZ OPTRO CPI 'S' ; SYSTEM FILES? JNZ HELP MVI A,80H ; SET FOR SYS FILES STA SYSTEM JMP OPTION OPTNUM: SUI '1' ; ADJUST '1' TO '8' TO 0-7 PUSH H ; SAVE PTR MOV E,A ; VALUE IN DE MVI D,0 LXI H,TAGS ; PT TO TAG BUFFER DAD D ; PT TO ELEMENT MVI M,80H ; SELECT ELEMENT POP H ; GET PTR TO NEXT CHAR JMP OPTION OPTCTRL: MVI A,0FFH ; CONTROL MODE STA CONTROL JMP OPTION OPTINS: MVI A,0FFH ; INSPECT STA INSPECT JMP OPTION OPTAR: MVI A,80H ; SET ARCHIVE STA ARCHIVE JMP OPTION OPTRO: MVI A,80H ; SET R/O STA READONLY JMP OPTION ; EXTRACT DISK, USER, AND FILE NAME INFORMATION DSPEC: LXI H,CMDLNE-1 ; PT TO BEFORE FIRST BYTE DSPEC0: INX H ; PT TO BYTE MOV A,M ; GET BYTE ORA A ; DONE? JZ HELP CPI ' ' ; ? JZ DSPEC0 ; ; MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS ; HL PTS TO FIRST BYTE OF NEXT FILE SPEC ; DSPEC1: CALL GETUD ; RESET USER IF NECESSARY LXI D,FCB ; PT TO FCB IN DE, PT TO FIRST CHAR OF FILE NAME IN HL PUSH H ; SAVE HL PTR CALL CODEND ; GET ADDRESS OF SCRATCH AREA MOV B,H ; ADDRESS IN BC MOV C,L POP H CALL ZFNAME ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER JZ DERR ; ERROR HANDLER SHLD NEXTCH ; SAVE PTR TO DELIMITER WHICH ENDED SCAN MOV A,C ; GET NEW USER STA USER ; SAVE IT MOV A,B ; SAVE POSSIBLE DRIVE SPEC CPI 0FFH ; CURRENT DISK? JZ USPEC LDA MDISK ; GET MAX DISK NUMBER DCR B ; ADJUST TO WITHIN BOUNDS 0-15 CMP B ; WITHIN BOUNDS? MOV A,B ; GET DISK NUMBER IN A JNC DSPEC2 DERR: CALL PRINT DB CR,LF,'Invalid Drive or User Specification',0 JMP RETURN ; LOG IN SPECIFIED DISK DSPEC2: PUSH B ; SAVE BC MOV E,A ; DISK NUMBER IN E LDA DOK ; OK TO DO SO? ORA A ; 0=NO JZ DNOK ; NOT ALLOWED ABORT MVI C,14 ; LOG IN DISK CALL BDOS POP B ; GET BC ; CHECK FOR USER NUMBER USPEC: MOV A,C ; GET NEW USER NUMBER CPI 0FFH ; DEFAULT USER? JZ PROT CPI '?' ; ALL USERS NOT ALLOWED? JZ UERR LDA MUSER ; GET MAX USER NUMBER CMP C MOV A,C ; USER NUMBER IN A JNC ULOG UERR: CALL PRINT DB CR,LF,'Invalid User Number',0 JMP RETURN ULOG: MOV E,A ; USER NUMBER IN E LDA UOK ; ALLOWED? ORA A ; 0=NO JZ UNOK ; DISALLOWED AND ABORT MVI C,32 ; SELECT USER CALL BDOS ; LOAD DIRECTORY AND PROTECT FILES PROT: CALL CODEND ; PT TO END OF CODE CALL RETUD ; GET CURRENT USER MOV A,C ; CURRENT USER IN A ORI 0C0H ; SELECT NON-SYS AND SYS FILES IN CURRENT USER LXI D,FCB ; PT TO FCB CALL DIRF ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE ; PROT DIR FILES; HL PTS TO FIRST FILE, BC=FILE COUNT CALL PROTFILES ; CHECK FOR NEXT FILE SPEC LHLD NEXTCH ; GET PTR MOV A,M ; GET DELIM CPI ',' ; ANOTHER FILE? JNZ PROTDONE INX H ; PT TO CHAR AFTER COMMA JMP DSPEC1 ; CONTINUE PROCESSING ; PROT COMPLETE -- PRINT COUNT AND EXIT PROTDONE: CALL PRCOUNT ; PRINT FILE COUNT JMP RETURN ; PROT SELECTED FILES PROTFILES: MOV A,B ; CHECK FOR ANY FILES LOADED ORA C RZ ; PRINT FILE NAME PROTLP: PUSH B ; SAVE ENTRY COUNT CALL CRLF ; NEW LINE PUSH H ; SAVE PTR TO FCB INX H ; PT TO FILE NAME MVI B,8 ; PRINT NAME CALL PRNT MVI A,'.' ; DECIMAL CALL COUT MVI B,3 ; PRINT TYPE CALL PRNT POP H ; GET PTR ; CHECK FOR CONTROL MODE AND PERFORM CONTROL FUNCTION IF SET LDA CONTROL ; GET FLAG ORA A ; NZ=YES JNZ PROTCTRL ; CHECK FOR INSPECTION AND INSPECT IF SET LDA INSPECT ; GET FLAG ORA A ; 0=NO JZ DOIT ; PROMPT USER FOR PROTECT CALL PROTQ ; PROT QUESTION CPI 'Q' ; QUIT? JZ QUIT CPI 'Y' ; YES? JZ DOIT ; DON'T PROTECT FILE NODO: CALL PRINT DB ' ++ NO Attribute Change ++',0 JMP PROTTEST ; PROMPT USER FOR PROT PROTQ: CALL PRINT ; PRINT PROMPT DB ' -- Protect (Y/N/Q=Quit/other=N)? ',0 CALL CIN ; GET RESPONSE CALL CAPS ; CAPITALIZE CALL COUT ; ECHO RET ; CONTROL FUNCTION -- ALLOW USER TO SET BITS AS HE DESIRES PROTCTRL: PUSH H ; SAVE PTR TO FILE XRA A ; A=0 STA READONLY ; CLEAR R/O, SYS, ARCHIVE, AND TAGS STA SYSTEM STA ARCHIVE LXI H,TAGS MVI B,8 CALL FILLB CALL PRINT DB ' -- Attributes (? for Help)? ',0 MVI A,0FFH ; CAPITALIZE CALL BBLINE ; INPUT LINE FROM USER CALL CRLF ; NEW LINE MVI B,80H ; MSB SET PCTRL: MOV A,M ; GET ATTRIBUTE FLAG ORA A ; DONE? JZ PDOIT ; DO PROTECTION THEN INX H ; PT TO NEXT CPI ' ' ; SKIP JZ PCTRL CPI 'Q' ; QUIT? JZ QUIT CPI 'A' ; ARCHIVE? JZ PCTRLA CPI 'S' ; SYSTEM? JZ PCTRLS CPI 'R' ; R/O? JZ PCTRLR CPI '1' ; DIGIT? JC PCTRLH ; HELP IF NOT CPI '8'+1 ; RANGE? JC PCTRLN ; DO NUMBER PCTRLH: CALL PRINT DB CR,LF,' You may issue the Q command to quit or select any' DB CR,LF,' arrangement of attributes that you desire.' DB CR,LF,' Attributes may be specified as follows --' DB CR,LF,' A = Archive, R = R/O, S = SYS, 1-8 = Tags' DB CR,LF,0 POP H ; GET FCB PTR POP B ; GET ENTRY COUNT JMP PROTLP ; PROCESS AGAIN PCTRLA: MOV A,B ; GET FLAG STA ARCHIVE ; SET FLAG JMP PCTRL PCTRLS: MOV A,B ; GET FLAG STA SYSTEM ; SET FLAG JMP PCTRL PCTRLR: MOV A,B ; GET AND SET FLAG STA READONLY JMP PCTRL PCTRLN: PUSH H SUI '1' ; CONVERT TO OFFSET MOV E,A ; OFFSET IN DE MVI D,0 LXI H,TAGS ; SET TAG DAD D MOV M,B ; SET BIT POP H JMP PCTRL ; CONTINUE ; QUIT PROTECT PROGRAM QUIT: CALL PRCOUNT ; PRINT COUNT OF FILES PROTECTED CALL PRINT DB CR,LF,' ++ QUIT -- Returning to CP/M ++',0 JMP RETURN ; PROT FILE, BUT GET PTR FIRST PDOIT: POP H ; GET PTR ; PROT FILE DOIT: PUSH H LXI D,PROTFCB ; COPY TARGET FILE INTO PROTECT'S FCB MVI B,16 ; 16 BYTES CALL MOVEB ; COPY LXI H,TAGS ; SET TAG BITS NOW INX D ; PT TO FIRST TAG BIT MVI B,8 ; 8 TAG BITS DOITL: LDAX D ; GET BYTE FROM PROT FCB ANI 7FH ; MASK OUT OLD MSB ORA M ; OR IN TAG BIT STAX D ; PUT BYTE BACK INX H ; PT TO NEXT INX D DCR B ; COUNT DOWN JNZ DOITL LDA READONLY ; GET R/O BIT MOV B,A ; SAVE IN B LDAX D ; GET BYTE ANI 7FH ; MASK OUT OLD MSB ORA B ; OR IN NEW MSB STAX D ; PUT IT BACK INX D ; PT TO SYS BIT LDA SYSTEM ; GET SYS BIT MOV B,A ; SAVE IT LDAX D ; GET BYTE ANI 7FH ; MASK OUT OLD MSB ORA B ; MASK IN NEW MSB STAX D ; PUT IT BACK INX D ; PT TO ARCHIVE BIT LDA ARCHIVE ; GET ARCHIVE BIT MOV B,A ; SAVE IT LDAX D ; GET BYTE ANI 7FH ; MASK OUT OLD MSB ORA B ; MASK IN NEW MSB STAX D ; PUT IT BACK LXI D,PROTFCB ; PT TO FCB CALL INITFCB ; INIT IT MVI C,30 ; SET FILE ATTRIBUTES CALL BDOS CALL PRINT DB ' Set to ',0 LXI H,PROTFCB+1 MVI B,8 ; 8 TAGS MVI C,'1' ; SET DIGIT PATTL1: MOV A,M ; GET BYTE ANI 80H ; PRINT ATT? JZ PATTL2 MOV A,C ; GET DIGIT CALL COUT PATTL2: INR C ; INCREMENT DIGIT INX H ; PT TO NEXT DCR B ; COUNT DOWN JNZ PATTL1 MOV A,M ; GET R/O BYTE ANI 80H ; MASK IT JZ PATTL3 CALL PRINT DB ' R/O ',0 JMP PATTL4 PATTL3: CALL PRINT DB ' R/W ',0 PATTL4: INX H ; PT TO SYS BYTE MOV A,M ; GET SYS BYTE ANI 80H ; MASK IT JZ PATTL5 CALL PRINT DB 'SYS',0 JMP PATTL6 PATTL5: CALL PRINT DB 'DIR',0 PATTL6: INX H ; PT TO ARCHIVE BYTE MOV A,M ; GET ARCH BYTE ANI 80H ; MASK IT JZ PATTL7 CALL PRINT DB ' AR',0 PATTL7: LHLD FILECNT ; INCREMENT FILE COUNT INX H SHLD FILECNT POP H ; GET PTR TO DIRECTORY ENTRY ; PT TO NEXT ENTRY PROTTEST: LXI D,ESIZE ; PT TO NEXT ENTRY DAD D POP B ; GET COUNT DCX B ; COUNT DOWN MOV A,B ; CHECK FOR ZERO ORA C JNZ PROTLP ; RETURN TO CALLER RET ; ; PRINT CHARS PTED TO BY HL FOR B BYTES ; PRNT: MOV A,M ; GET CHAR CALL COUT INX H ; PT TO NEXT DCR B ; COUNT DOWN JNZ PRNT RET ; ; PRINT COUNT OF NUMBER OF FILES PROTECTED ; PRCOUNT: CALL CRLF ; NEW LINE CALL PRINT DB CR,LF,'++ ',0 LHLD FILECNT ; GET COUNT MOV A,L ; CHECK FOR NONE ORA H JZ PRNO CALL PHLDC ; PRINT DECIMAL COUNT JMP PRMS PRNO: CALL PRINT DB 'No ',0 PRMS: LHLD FILECNT ; 1 FILE PROTECTED? MOV A,H ; HIGH ZERO? ORA A JNZ PRMULT MOV A,L ; LOW ONE? CPI 1 JZ PRSING PRMULT: CALL PRINT DB ' Files Protected ++',0 RET PRSING: CALL PRINT DB ' File Protected ++',0 RET ; ; BUFFERS ; INSPECT: DS 1 ; INSPECT FLAG (0=NO, 0FFH=YES) CONTROL: DS 1 ; CONTROL FLAG (0=NO, 0FFH=YES) ARCHIVE: DS 1 ; ARCHIVE FLAG (0=NO, 80H=YES) SYSTEM: DS 1 ; SYSTEM FLAG (0=NO, 80H=YES) READONLY: DS 1 ; READ/ONLY FLAG (0=NO, 80H=YES) TAGS: DS 8 ; 8 TAG BITS USER: DS 1 ; NEW USER, OR 0FFH IF NO CHANGE NEXTCH: DS 2 ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE FILECNT: DS 2 ; COUNT OF NUMBER OF FILES PROTECTED PROTFCB: DS 40 ; FCB FOR PROTECT CMDLNE: DS 256 ; ALLOW MAX SIZE OF COMMAND LINE DS 100 ; STACK AREA STACK: DS 2 ; OLD STACK PTR END