;*; Updated on 15-Aug-89 at 9:04 AM by Cary Fitch; edit time: 0:40:57
;*************************** AMUS Program Label ******************************
; Filename: POP.M68                                         Date: 07/15/89
; Category: UTIL         Hash Code: 257-422-265-612      Version: 1.0(103)
; Initials: CARY         Name: CARY FITCH
; Company: NATIONAL TELEVISION SYSTEMS             Telephone #: 5123432067
; Related Files: PUSH.M68, LIB.UNV  (DON'T FORGET THIS FILE!)
; Min. Op. Sys.: 1.3                           Expertise Level: BEG
; Special: You must LNKLIT this program after assembly
; Description: This program, (used along with PUSH), will move you back to
; previous log-in accounts.  This makes for a much quicker return-path after
; moving around the system.  For more help on its use type: POP ?.
; FIXED IMPROPER IMPURE AREA INDEXING WHICH CAUSED "MEMORY MAP DISTROYED"
; ERROR AT 15TH POP. EXTENDED POP CAPABILITY TO HOWEVER MANY LEVELS ARE IN
; MEMORY MODULE. CF
;*****************************************************************************
;*************************** AMUS Program Label ******************************
; Filename: POP.M68                                         Date: 07/01/89
; Category: UTIL         Hash Code: 756-333-332-336      Version: 1.0(102)
; Initials: PSS          Name: DENNIS W. NEDER
; Company: PROFESSIONAL SOFTWARE SYSTEMS           Telephone #: 8189575930
; Related Files: PUSH.M68, LIB.UNV  (DON'T FORGET THIS FILE!)
; Min. Op. Sys.: 1.3                           Expertise Level: BEG
; Special: You must LNKLIT this program after assembly
; Description: This program, (used along with PUSH), will move you back to
; previous log-in accounts.  This makes for a much quicker return-path after
; moving around the system.  For more help on its use type: POP ?.
;*****************************************************************************
;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; *     POP.M68                                                         *
; *                                                                     *
; *     This program allows a user to POP the next account spec         *
; *     off of the memory-resident stack and into the job table         *
; *     thus logging the user there.                                    *
; *                                                                     *
; *     An optional switch (/D) allows the user to delete the current   *
; *     account from the stack.  A second optional switch (/K) will     *
; *     kill off the memory module ACCNTS.PSH.  One final switch (/N)   *
; *     specifies a No-Delete operation where the current account is    *
; *     not to be removed after the re-load.                            *
; *                                                                     *
; *     Copyright (c) 1988 by Dennis W. Neder                           *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
; Edits:
;       31-Dec-85       Created/DWN
;       06-Jan-86       Added /N switch/DWN
;       22-Jan-86       Added Ersatz support/DWN
;       15-JUL-89       FIXED IMPURE ADDRESSING/CARY
;       15-JUL-89       MADE PROGRAM ADAPT TO ALL LEVELS IN MODULE/CARY
; Universals:

       EXTERN  $FNPPN
       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM
       SEARCH  LIB
       ASMMSG  "You must link this program after assembly."

; Version:

       VMAJOR=1
       VEDIT=100.                      ; 31-Dec-85 Created/DWN
       VEDIT=101.                      ; 06-Jan-86 /N switch added/DWN
       VEDIT=103.                      ; 22-Jan-86 Ersatz support/DWN

; Local equates:

       JOB=A0
       IMP=A5

; Layout of account module with memory

       M.DEV=0                         ; Device name
       M.DRV=2                         ; Drive number
       M.PPN=4                         ; PPN
       M.SIZ=6                         ; Size of buffer

       .OFINI
       .OFDEF  DDB,D.DDB               ; DDB for verification of account
       .OFDEF  JOBBUF,6                ; Buffer for job's log information
       .OFSIZ  IMPSIZ

HDR:    PHDR    -1,0,PH$REU

START:  JOBIDX  JOB                     ; Get our current job table index
       MOVW    JOBTYP(JOB),D5          ; Save our job type word for later
       ANDW    #^C<J.HEX>,JOBTYP(JOB)  ; Temporarily for octal
       SRCH    MOD,IMP                 ; Locate our memory module
       BEQ     10$
       TYPECR  ?ACCNTS.PSH not found in user memory
       JMP     EXIT

;
; Begin command line checking here (for switches)
;
10$:    LEA     A1,NODEL                ; Get address of NO-Del switch
       MOVB    #0,@A1                  ;  And clear it!
       BYP
       LIN                             ; Was a switch specified?
       JEQ     LODACC                  ; No - POP next Account
       CMPB    @A2,#'/                 ; Was a switch specified?
       BNE     HELP
       INC     A2                      ; Bump command line pointer
       CMPB    @A2,#'D                 ; Was Delete requested?
       JEQ     DELACC
       CMPB    @A2,#'K                 ; Was Kill requested?
       JEQ     KILMOD                  ; Yes - remove memory module
       CMPB    @A2,#'N                 ; Was No-delete requested?
       BNE     20$
       LEA     A1,NODEL                ; Get address of NODEL Switch
       MOVB    #-1,@A1                 ;  and set it
       JMP     LODACC

20$:    TYPECR  ?Illegal switch specified
       CRLF

HELP:   CRT     #11.
       TTYI
       ASCIZ   "Format: "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   ".POP"
       EVEN
       CRT     #11.
       TTYI
       ASCII   " {/K}{/U}{/N}{?}"
       BYTE    15,15
       ASCIZ   "This program (in conjunction with "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH.LIT"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "), will let you quickly move from"
       BYTE    15
       ASCII   "one account to another.  "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "POP"
       EVEN
       CRT     #11.
       TTYI
       ASCIZ   " will restore the last account "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "ed into your"
       BYTE    15
       ASCII   "job table, thus logging you there."
       BYTE    15,15,0
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "POP"
       EVEN
       CRT     #11.
       TTYI
       ASCII   " will check the account for a password and require you to enter it if one"
       BYTE    15
       ASCII   "exists before logging into that account."
       BYTE    15,15
       ASCII   "Optional Switches:"
       BYTE    15
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "/K "
       EVEN
       CRT     #11.
       TTYI
       ASCII   "- Kill ACCNTS.PSH from memory."
       BYTE    15
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "/D "
       EVEN
       CRT     #11.
       TTYI
       ASCIZ   "- Delete last account "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "ed without logging there."
       BYTE    15,0
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "/N "
       EVEN
       CRT     #11.
       TTYI
       ASCII   "- No-Delete of last account after loading into job table."
       BYTE    15,0
       EVEN
       CRT     #12.
       JMP     EXIT

;
; This section of code is called in response to an attempted logging
;
LODACC: PUSH    IMP                     ; Save pointer to number of accounts
       CALL    GETACC                  ; Get index to last account
       JEQ     NOACCT                  ; Zero flag = no accts in mem
       GETIMP  IMPSIZ,A2,EXIT          ; Allocate temporary storage
       INIT    @A2                     ; Initialize DDB
       MOVW    M.DEV(IMP),DDB+D.DEV(A2); Get device name into DDB
       MOVW    M.DRV(IMP),DDB+D.DRV(A2); Get drive number into DDB
       MOVW    M.PPN(IMP),DDB+D.PPN(A2); Get PPN into DDB
       CLR     D1                      ; Pre-clear D1
       MOVW    M.PPN(IMP),D1           ; Get PPN into D1
       CALL    $FNPPN                  ; See if account exists
       BEQ     10$                     ; Yes - OK to load
       POP     IMP                     ; Clean up stack
       TYPESP  ?Cannot POP into
       CALL    SHOACC                  ; Display the account
       TYPECR  < - account does not exist>
       JMP     REMACC                  ; Go remove account

10$:    TST     MF.PSW(A1)              ; A1 -> MFD entry:  Test for Password
       BEQ     20$
       MOV     MF.PSW(A1),D4           ; Get password
       CALL    PSW                     ; Get password for this account
       JNE     EXIT                    ; Wrong password; don't delete account tho!
       CRLF

20$:    MOVW    JOBDEV(JOB),JOBBUF+M.DEV(A2) ; Save job table info
       MOVW    JOBDRV(JOB),JOBBUF+M.DRV(A2)
       MOVW    JOBUSR(JOB),JOBBUF+M.PPN(A2)
       MOVW    M.DEV(IMP),JOBDEV(JOB)  ; Move device into job table
       MOVW    M.DRV(IMP),JOBDRV(JOB)  ; Move drive into job table
       MOVW    M.PPN(IMP),JOBUSR(JOB)  ; Move PPN into job table
       MOV     IMP,A4                  ; Save temporarily
       LEA     IMP,JOBBUF(A2)
       CRT     #11.
       TYPESP  POPed from
       CRT     #12.
       CALL    SHOACC                  ; Display account
       CRT     #11.
       TYPESP  < to>
       CRT     #12.
       MOV     A4,IMP                  ; Restore pointer
       CALL    SHOACC
       CRLF
       CALL    CHKERS                  ; Handle ersatz name if applicable      [102]
       BR      BYEACC                  ; Go clean up memory

;
; This section of code is used to delete an account from the user's memory
; module.
;
DELACC: PUSH    IMP                     ; Save pointer to number of accounts
       CALL    GETACC                  ; Get index to last account
       JEQ     NOACCT                  ; Zero flag means no accounts in module
       CRT     #11.
       TYPESP  Account:
       CRT     #12.
       CALL    SHOACC                  ; Display account to be deleted
       CRT     #11.
       TYPECR  < deleted>
       CRT     #12.
       CRLF

BYEACC: POP     IMP                     ; Restore pointer to number of accounts
       LEA     A1,NODEL                ; Address No-Del switch
       TSTB    @A1                     ; Was switch set?
       JNE     EXIT

REMACC: DECW    @IMP                    ; Delete by reducing number of accounts
       BR      EXIT

NOACCT: TYPECR  ?No accounts have been PUSHed
       BR      EXIT

;
; This section of code removes the memory module from the user's partition.
; Note that the module flags are simply reset.  AMOS will take care of the
; rest during the processing of EXIT.
;
KILMOD: XORW    #<FIL!LOK>,-10(IMP)     ; Reset header information
       CRT     #11.
       TYPESP  Memory module:
       CRT     #12.
       TYPESP  ACCNTS.PSH
       CRT     #11.
       TYPECR  deleted
       CRT     #12.

EXIT:   MOVW    D5,JOBTYP(JOB)          ; Restore J.HEX context
       EXIT

;
; Begin subroutines here.
;
; This subroutine will locate the last account pushed into the memory
; module and return it's address to the caller, or a zero-flag condition
; is returned if there are no more accounts.
;
GETACC: MOVW    (IMP)+,D0               ; Get number of accounts
       BNE     10$                     ; If number of accounts > 0
       RTN

10$:    DEC     D0                      ; Adjust number of accounts
       MOV     #M.SIZ,D2               ; Get account module size
       MUL     D0,D2                   ; Calculate offset of last account
       ADD     D0,IMP                  ;  and index it with A5
       LCC     #0                      ; Clear Zero flag for successful
       RTN

;
; This subroutine displays the account at the current location within the
; user's memory module.
;
SHOACC:
       MOV     IMP,A1                  ; Get index to device name
       LEA     A2,PBUF                 ; Address print buffer
       UNPACK                          ; To ASCII
       CLRB    @A2                     ; Null at end
       LEA     A6,PBUF                 ; Index print buffer
       TTYL                            ; Display device name
       CLR     D1                      ; Pre-clear D1
       MOVW    (A1)+,D1                ; Get drive number
       DCVT    0,OT$TRM                ; Put it into buffer
       TYPE    :[
       CLR     D3                      ; Pre-clear D3
       MOVW    (A1)+,D3                ; Get Project Number
       MOV     D3,D1                   ; Load PPN
       RORW    D1,#8.                  ; Shift Project number into position
       AND     #377,D1                 ; Mask off crap
       OCVT    0,OT$TRM!OT$ZER         ; Output to screen
       TYPE    <,>
       MOV     D3,D1                   ; Reload PPN
       AND     #377,D1                 ; Mask off crap
       OCVT    0,OT$TRM                ; And load it into memory
       TYPE    ]
       RTN

;
; This subroutine gets the password required to POP into an account that
; has been so protected.  If the password is entered correctly, the zero-
; flag is set.  An incorrect entry causes a zero-flag reset condition.
;
PSW:    PUSH                            ; Get 8 bytes of work area
       PUSH
       TYPESP  <Password:>
       MOV     JOBTRM(JOB),A6          ; Index terminal definition
       ORW     #T$IMI!T$ECS,@A6        ; Image mode, echo suppress
       CLR     D0
       MOV     SP,A1

20$:    KBD     60$
       CMPB    D1,#15                  ; Return?
       BEQ     50$
       CMPB    D1,#177                 ; Del?
       BEQ     30$
       CMPB    D1,#10                  ; Backspace?
       BEQ     30$
       CMPB    D1,#25                  ; ^U?
       BEQ     40$                     ; Wipe out entire line
       CMPB    D1,#40                  ; => Space?
       BLO     20$                     ; Invalid character
       CMPB    D1,#177                 ; < Del?
       BHI     20$                     ; Invalid character
       CMP     D0,#6                   ; Buffer full?
       BHIS    25$
       MOVB    D1,(A1)+                ; It's OK - move into buffer
       INC     D0
       BR      20$

25$:    MOVB    #7,D1                   ; Buffer full - ring terminal bell
       TTY
       BR      20$

30$:    TST     D0                      ; Anything to rubout?
       BEQ     20$                     ; No - ignore it
       DEC     D0                      ; Else uncount it
       DEC     A1                      ; Backup the pointer
       BR      20$

40$:    CLR     D0                      ; Clear the counter
       MOV     SP,A1                   ; Reset pointer
       BR      20$

50$:    CLRB    @A1                     ; Begin processing of password
       MOV     SP,A2                   ; Index work area (Password)
       PUSH                            ; Get more work space
       MOV     SP,A1                   ; Index work area
       PACK                            ; Pack entered password
       PACK
       POP     D0                      ; Get password into D0
       POP                             ; Clean up workspace
       POP
       CMP     D0,D4                   ; Does it match password
       BEQ     70$

60$:    MOVB    #7,D1                   ; Queue up bell
       TTY
       CRLF
       TYPECR  <?Bad password>
       LCC     #0                      ; Set condition codes

70$:    RTN

;
; This subroutine processes ersatz names if applicable
;
CHKERS: CALL    FNDERS                  ; See if we have an ersatz name
       BNE     10$                     ; No name - bypass print
       CRT     #11.
       TYPESP  <Ersatz name is>
       CRT     #12.
       CALL    PRTERS                  ; Print name on terminal
       CRLF
10$:    RTN                             ; Back to caller

;
; This subroutine finds the ersatz name in ersatz table if applicable.  If
; found, return with Z-bit set and A1 pointing to table entry.
;
FNDERS: CMPW    JOBESZ,#JOBTBE          ; Check monitor version
       BLO     40$                     ; Not under 1.3 - don't check table
       TST     ERSATZ                  ; Check ersatz index
       BEQ     40$                     ; Zero means no table exists
10$:    MOV     ERSATZ,A1               ; Index ersatz table
20$:    CMMW    EZ.PPN(A1),JOBUSR(A0)   ; Does this entry have the same account?
       BNE     30$
       CMMW    EZ.DEV(A1),JOBDEV(A0)   ; Does this entry have the same device?
       BNE     30$
       CMMW    EZ.UNT(A1),JOBDRV(A0)   ; Does this entry have the same unit?
       BEQ     50$                     ; Yes - Zero flag set
30$:    ADDW    #EZ.SIZ,A1              ; Skip to next ersatz account
       TSTW    @A1                     ; End of the table?
       BNE     20$
40$:    MOV     #1,D7                   ; Clear Z-bit for not found
50$:    RTN

;
; This subroutine displays the Ersatz name on the user's terminal.  The
; ersatz name is indexed by A1.
;
PRTERS: LEA     A1,EZ.NAM(A1)           ; Index ersatz name in table
       LEA     A2,PBUF                 ; unpack ersatz into buffer
       UNPACK
       UNPACK
10$:    CMPB    -(A2),#40               ; Is this character a space?
       BNE     20$                     ; No - done
       CLRB    @A2                     ; Yes - clear it
       BR      10$                     ;  and check for next
20$:    TTYL    PBUF                    ; print ersatz name it
       TYPE    <:>
       RTN

;
; Begin data section here.
;
MOD:    RAD50   /ACCNTSPSH/
       EVEN

PBUF:   BLKL    2                       ; Print buffer
NODEL:  BLKB    1                       ; Switch storage
       EVEN

       END