;*************************** AMUS Program Label ******************************
; Filename: DEVCHE.M68                                      Date: 1/29/92
; Category: UTIL         Hash Code: 773-447-611-653      Version: 1.0(100)
; Initials: TREE/AM      Name: DELL COLEMAN
; Company: Alpha Automation Incorporated           Telephone #: 7138778039
; Related Files: AAI.M68
; Min. Op. Sys.: 2.0                           Expertise Level: BEG
; Special:
; Description: Lock/Unlock UFDs into CACHE.  Uses CMDLIN wildcarding.
;
;
;*****************************************************************************
;*ML DEVCHE- Lock UFD's into disk cache
;
; Written by:
;       Dell Coleman
;       Alpha Automation Incorporated
;       2000 West Loop South
;       Houston, Texas 77027
;       (713) 877-8039
;           and copyrighted by the same in 1991.
;
;       For a description of the workings of CMDLIN.SYS look at articles
;       3.4.5 & 3.4.7 in the software volume of the AMTS Journal
;
; Register Usage:
;       A1 - Next entry in device table chain
;       A2 - Input line address
;       A4 - Address of DDB for DCACHE
;       A5 - Impure area address
;
; Edit history
;[100] 6 November 1991  Dell Coleman
;       Program written.
;
       VMAJOR=1
       VMINOR=0
       VEDIT=100.

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM
       SEARCH  AAI
       COPY    CMDSYM                  ; CMDLIN.SYS stuff

       ASECT                           ; Our Impure area starts here
       .=IMP.SZ                        ; Continue from CMDSYM
INDDB:  BLKB    D.DDB                   ; Used for input files
INBUF:  BLKB    512.                    ; Buffer for DDB
CHRTBL: BLKB    DC.SIZ                  ; Device Characteristics table
SAVEA2: BLKL    1                       ; Save A2 (for CMDLIN)
SWVAL:                                  ; Results of command line switches
LOCK:   BLKL    1                       ; Lock switch
UNLOCK: BLKL    1                       ; Unlock switch
IMP.SZ=.                                ; IMP.SZ is inpure area size

       .=0                             ; Beginning of program
       PSECT

DEVCHE: PHDR    -1,0,PH$REE!PH$REU
       GETIMP  IMP.SZ,A5,NOMEM         ; Branch to NOMEM if not enough memory

       LEA     A6,INBUF(A5)            ; Addr of buffer to A6
       MOV     A6,D.BUF+INDDB(A5)      ; Put in DDB
       MOV     #512.,D.SIZ+INDDB(A5)   ; Put buffer size into DDB
       MOVB    #D$INI,D.FLG+INDDB(A5)  ; Tell INIT we have a buffer
       INIT    INDDB(A5)               ; INITialize DDB for CMDLIN

       MOV     A2,SAVEA2(A5)           ; Save A2 for CMDLIN
       .CMLOC  INDDB(A5)               ; Locate CMDLIN.SYS (Load if necessary)
       LEA     A0,DEFCMD               ; Addr of default command to A0
       MOV     #OP$PRT!OP$TRN,D7       ; CMDLIN flags
       .CMINI  SWDEF,SWVAL(A5)         ; Initialize CMDLIN
       JNE     ERRXIT                  ; Set error flag and exit (On error)
       AND     #IN$OFP,D7              ; Was output specified?
       JNE     NOOUT                   ; Branch if yes (error)

       LEA     A4,INDDB(A5)            ; Put addr of DDB in A4
       LEA     A1,DEVTBL               ; Address of device table to A1

NXTDEV: CTRLC   ERRXIT                  ; Check for ^C
       MOV     DT.NXT(A1),D7           ; Addr of next entry in devtbl to D7
       JEQ     EXIT                    ; Branch if end of table
       MOV     D7,A1                   ; Addr of DEVTBL entry to A1
       MOVW    DT.DEV(A1),D.DEV+INDDB(A5)      ; Device name to DDB
       MOVW    DT.DRV(A1),D.DRV+INDDB(A5)      ; Device number to DDB
       INIT    INDDB(A5)               ; INITialize DDB (for DEVCHR)
       DEVCHR  INDDB(A5),CHRTBL(A5)    ; Get device characteristics
       MOV     DC.FLG+CHRTBL(A5),D7    ; Characteristics flag word to D7
       AND     #<DC$FSD!DC$MNT>,D7     ; Remove all unwanted bits
       CMP     D7,#<DC$FSD!DC$MNT>     ; Is device file structured & mounted?
       BNE     NXTDEV                  ; Branch if not
       DIRACC  INDDB(A5),#DA$INI!DA$NEW        ; Get directory access

NXTPPN: CTRLC   ERRXIT                  ; Check for ^C
       DIRSCH  INDDB(A5),#DS$DIR       ; Get next PPn
       TSTW    D6                      ; End of entries?
       BMI     NXTDEV                  ; Branch if yes
       MOVW    D.FIL+INDDB(A5),D.PPN+INDDB(A5) ; Standard file format DDB
       MOV     #<[A  ]_16.![   ]>,D.FIL+INDDB(A5) ; Set filename to A.A
       MOVW    #[A  ],D.EXT+INDDB(A5)
       LEA     A0,DEFCMD               ; Addr of default command to A0
       MOV     #OP$PRT!OP$TRN,D7       ; CMDLIN flags
       MOV     SAVEA2(A5),A2           ; Restore A2
       .CMINI  SWDEF,SWVAL(A5)         ; Re-initialize CMDLIN

10$:    CTRLC   ERRXIT                  ; Check for ^C
       .CMCMP                          ; Does this file spec match?
       BNE     50$                     ; Branch if yes
       .CMSKP                          ; Try next entry
       JNE     ERRXIT                  ; Error (exit)
       AND     #NX$END,D7              ; Check for at end
       BNE     NXTPPN                  ; Branch if yes
       BR      10$                     ; Try this entry

50$:    OFILE   INDDB(A5),OT$TRM!OT$OFD ; Print device spec on terminal
       TYPE    <[>
       PRPPN   D.PPN+INDDB(A5)         ; Print PPn on terminal
       TYPE    <]>
       .CMQRY                          ; Check for /Q answer
       JEQ     NXTPPN                  ; Branch if no
       MOV     LOCK(A5),D7             ; Check for switches
       ADD     UNLOCK(A5),D7           ; Only Lock or Unlock is valid
       CMP     D7,#-1                  ;
       JNE     BADSW                   ; Branch if no or multiple switches
       TST     LOCK(A5)                ; Is lock switch on?
       BEQ     60$                     ; Branch if not

       MOV     #DC.LU,D7               ; Lock UFD into cache
       MOV     DCACHE,A6               ; Addr of DCACHE.SYS to A6
       CALL    @A6
       JEQ     NXTPPN                  ; Get next PPn
       BR      ERRCHE                  ; Print error message & exit

60$:    MOV     #DC.UU,D7               ; Unlock UFD from cache
       MOV     DCACHE,A6               ; Addr of DCACHE.SYS to A6
       CALL    @A6
       JEQ     NXTPPN                  ; Get next PPn

ERRCHE: TSTB    D.ERR+INDDB(A5)         ; Was error code put into DDB?
       BNE     10$                     ; Branch if yes
       TYPECR  <?CACHE system reported an error, but did not specify>
       BR      ERRXIT
10$:    ERRMSG  D.ERR+INDDB(A5),OT$LDQ!OT$TRM   ; Print error message

ERRXIT: JOBIDX  A6                      ; Address of our JCB to A6
       TSTW    JOBERR(A6)              ; Error flag already set?
       BNE     EXIT                    ; Branch if yes
       SETERR  0,JE$MSC                ; Set error flag

EXIT:   EXIT

NOMEM:  TYPECR  <Insufficient free memory to execute>
       BR      ERRXIT
NOOUT:  TYPECR  <Output specifications are not allowed>
       BR      ERRXIT
BADSW:  TYPECR  <Either LOCK or UNLOCK must be specified>
       JMP     ERRXIT
       EVEN

SWDEF:  WORD    2                       ; CMDLIN Switch count
       WORD    SWTYP-SWDEF             ; Offset to switch types table
       WORD    SWOFF-SWDEF             ; Offset to off values table
       WORD    SWON-SWDEF              ; Offset to on values table
       WORD    SWTXT-SWDEF             ; Offset to switch names table
SWTYP:  WORD    0                       ; LOCK switch type
       WORD    0                       ; UNLOCK switch type
SWOFF:  LWORD   0                       ; LOCK off value
       LWORD   0                       ; UNLOCK off value
SWON:   LWORD   -1                      ; LOCK on value
       LWORD   -1                      ; UNLOCK on value
SWTXT:  ASCIZ   /LOCK/
       ASCIZ   /UNLOCK/
DEFCMD: ASCIZ   /=*.*/
       EVEN

       END