Files
RomWBW/Source/Images/d_bp/u15/PROTECT.MAC
2020-01-03 20:42:06 -08:00

591 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; PROGRAM: PROTECT
; VERSION: 3.0
; DATE: 18 May 84
; AUTHOR: RICHARD CONN
; PREVIOUS VERSIONS: 2.0 (16 Jan 83)
; 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 30
z3env SET 0f400h
;
; PROTECT Command --
; PROTECT is used to set the file protection and tag attribute bits
; for CP/M 2.x files in the ZCPR3 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 DIRQ ; DIRECTORY PROCESSOR
EXT Z3INIT ; INIT BUFFERS
EXT ZFNAME ; FILE NAME PROCESSOR
EXT Z3LOG ; LOG INTO Z3 DU
EXT BBLINE ; INPUT LINE EDITOR
EXT INITFCB ; INIT FCB
EXT BDOS ; BDOS ENTRY
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 ; <CR>
LF EQU 10 ; <LF>
;
; Environment Definition
;
if z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
jmp start
db 'Z3ENV' ;This is a ZCPR3 Utility
db 1 ;External Environment Descriptor
z3eadr:
dw z3env
start:
lhld z3eadr ;pt to ZCPR3 environment
;
else
;
; Internal ZCPR3 Environment Descriptor
;
MACLIB Z3BASE.LIB
MACLIB SYSENV.LIB
z3eadr:
jmp start
SYSENV
start:
lxi h,z3eadr ;pt to ZCPR3 environment
endif
;
; Start of Program -- Initialize ZCPR3 Environment
;
call z3init ;initialize the ZCPR3 Env and the VLIB Env
LXI H,0 ; GET STACK PTR
DAD SP
SHLD STACK ; SAVE IT
CALL CODEND ; DETERMINE FREE SPACE
SHLD CMDLNE ; COMMAND LINE BUFFER
LXI D,100H ; BUFFER SIZE
DAD D
SHLD DIRBUF ; DIR BUFFER
SPHL ; SET SP
CALL PUTUD ; SAVE CURRENT USER/DISK AWAY
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,'Syntax:'
DB CR,LF,' PROTECT dir:filename.typ,dir:fn.ft,... o...'
DB CR,LF,'Options:'
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
DB 0
; RETURN TO OS
RETURN:
LHLD STACK ; GET OLD STACK
SPHL ; SET IT
RET
; COPY BUFFER INTO TEMP BUFFER
ECONT:
LHLD CMDLNE ; PT TO CMDLNE BUFFER
XCHG
LXI H,BUFF+1 ; PT TO BUFFER
MVI B,80H ; ARBITRARY
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
LHLD CMDLNE ; PT TO BUFFER
; SKIP TO FILE NAME STRING
SBLANK:
MOV A,M ; SKIP TO NON-BLANK
CPI ' ' ; <SP>?
JNZ SBL1
INX H ; PT TO NEXT CHAR
JMP SBLANK
; SKIP TO END OF FILE NAME STRING
SBL1:
MOV A,M ; SKIP TO <SP> OR EOL
ORA A ; DONE?
JZ OPT
CPI ' ' ; <SP>
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:
LHLD CMDLNE ; PT TO BEFORE FIRST BYTE
DCX H
DSPEC0:
INX H ; PT TO BYTE
MOV A,M ; GET BYTE
ORA A ; DONE?
JZ HELP
CPI ' ' ; <SP>?
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
MVI A,0 ; DIR BEFORE DU
CALL ZFNAME ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER
SHLD NEXTCH ; SAVE PTR TO DELIMITER WHICH ENDED SCAN
LXI D,FCB ; PT TO FCB
CALL Z3LOG ; LOG INTO DU
; LOAD DIRECTORY AND PROTECT FILES
PROT:
LHLD DIRBUF ; PT TO END OF CODE
MVI A,0C0H ; SELECT NON-SYS AND SYS FILES
LXI D,FCB ; PT TO FCB
CALL DIRQ ; 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 <SP>
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,' Attributes may be specified as follows --'
DB CR,LF,' A = Archive, R = R/O, S = SYS, 1-8 = Tags'
DB CR,LF,' The command Q exits'
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',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
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
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 2 ; PTR TO COMMAND LINE SAVE AREA
DIRBUF:
DS 2 ; DIRECTORY BUFFER
STACK:
DS 2 ; OLD STACK PTR
END