;*; Updated on 15-Aug-89 at 9:03 AM by Cary Fitch; edit time: 1:32:29
;*************************** AMUS Program Label ******************************
; Filename: PUSH.M68                                        Date: 08/15/89
; Category: UTIL         Hash Code: 414-217-330-156      Version: 1.0(101)
; Initials: CARY         Name: CARY FITCH
; Company: NATIONAL DATA SYSTEMS                   Telephone #: 5123432067
; Related Files: POP.M68, LIB.UNV  (DONT FORGET THIS FILE!)
; Min. Op. Sys.: 1.3                           Expertise Level: BEG
; Special: You must LNKLIT this program after assembly!
; Description: Will "Remember" up to 30 logs.  You can then "POP" back to them
; in reverse order.  Will also list accounts PUSHed.  Use: PUSH ? for help.
; NOW HAS PERPETUAL STACK, WILL NEVER RUN OUT OF MEMORY, WILL REMEMBER LAST
; 30 ENTRIES.
;*****************************************************************************
;*************************** AMUS Program Label ******************************
; Filename: PUSH.M68                                        Date: 07/01/89
; Category: UTIL         Hash Code: 332-022-660-003      Version: 1.0(100)
; Initials: PSS          Name: DENNIS W. NEDER
; Company: PROFESSIONAL SOFTWARE SYSTEMS           Telephone #: 8189575930
; Related Files: POP.M68, LIB.UNV  (DONT FORGET THIS FILE!)
; Min. Op. Sys.: 1.3                           Expertise Level: BEG
; Special: You must LNKLIT this program after assembly!
; Description: Will "Remember" up to 10 logs.  You can then "POP" back to them
; in reverse order.  Will also list accounts PUSHed.  Use: PUSH ? for help.
;
;*****************************************************************************
; ***********************************************************************
; *     PUSH.M68                                                        *
; *                                                                     *
; *     This program allows a user to PUSH his current device and       *
; *     account (or one specified) into a memory-resident module        *
; *     and later POPed back into JOBUSR.  Up to XX accounts may        *
; *     be stored at one time.  This can be increased by changing       *
; *     M.NBR to the required number and re-assembling this module.     *
; *                                                                     *
; *     Copyright (c) 1988 by Dennis W. Neder                           *
; ***********************************************************************
;
; Edits:
;       31-Dec-85       Created./DWN
;       15-JUL-89       MODIFIED - CARY FITCH
; Universals:

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

; Version:

       VMAJOR=1
       VEDIT=100.              ; 31-Dec-85 Created/DWN
       VEDIT=101.              ; 01-Jul-89 provided perpetual stack [CF-101
                               ;           made use of N.PPN universal "
; Local equates:

       JOB=A0
       IMP=A5
       M.DEV=0                 ; Device within buffer
       M.DRV=2                 ; Drive number
       M.PPN=4                 ; Account
       M.SIZ=6                 ; Size of each account buffer
       M.NBR=30.               ; Number of accounts that can be stored
                               ;  set for 10 accounts - expand as needed.

; Local memory module definition:

       .OFINI
       .OFDEF  N.PPN,2         ; Number of Accounts currently resident
       .OFDEF  STOR,M.SIZ*M.NBR; PPN storage - 6 bytes x X Accounts
       .OFDEF  PBUF,7          ; Print buffer
       .OFSIZ  IMPSIZ

; Separate impure area for DDB used in verifying the PPN supplied by the user:

       .OFINI
       .OFDEF  DDB,D.DDB       ; DDB for locating PPN
       .OFSIZ  PPNSIZ

HDR:    PHDR    -1,0,PH$REE!PH$REU

START:  JOBIDX  JOB             ; Get our job table index
       MOVW    JOBTYP(JOB),D5  ; Store for later
       ANDW    #^C<J.HEX>,JOBTYP(JOB) ; Temporarily reset hex/octal bit
;       CRLF
;       NAME    HDR
;       CRLF
;       TYPECR  Copyright (c) 1988 by Dennis W. Neder
;       CRLF

;
; The following code finds and addresses (or creates) the user's memory
; module.
;
FNDMOD: SRCH    MOD,IMP         ; See if we have a module already in memory
       BEQ     10$             ; Yes - no need to rebuild it
       GETIMP  IMPSIZ,IMP,EXIT ; No - create one
       MOV     IMP,A1          ; Get index to memory module
       MOVW    #[PSH],-(A1)    ;  and load module name
       MOVW    #[NTS],-(A1)
       MOVW    #[ACC],-(A1)
       ORW     #<FIL!LOK>,-(A1); Lock module in memory (Only POP will remove)

10$:    BYP
       CMPB    @A2,#'?         ; Help requested?
       JNE     CHKSW

HELP:   CRT     #11.
       TTYI
       ASCIZ   "Format: "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   ".PUSH "
       EVEN
       CRT     #11.
       TTYI
       ASCII   "{Account-spec}{/L}{?}"
       BYTE    15,15
       ASCIZ   "This program (in conjunction with "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "POP.LIT"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "), will let you quickly move from"
       BYTE    15
       ASCIZ   "one account to another.  "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   " will load your current account or one specified"
       BYTE    15
       ASCIZ   "into a memory module named "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "ACCNTS.PSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   " that is locked in memory.  You may then"
       BYTE    15,0
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "POP"
       EVEN
       CRT     #11.
       TTYI
       ASCIZ   " yourself into that account when desired.  "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   " will verify that the account"
       BYTE    15
       ASCII   "exists before loading it."
       BYTE    15,15
       ASCIZ   "Up to 30 accounts may be stored at one time.  The accounts may then be "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "POP"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "ed"
       BYTE    15
       ASCII   "in reverse order."
       BYTE    15,15
       ASCII   "Optional Switches:"
       BYTE    15,0
       CRT     #12.
       TTYI
       ASCIZ   "/L "
       EVEN
       CRT     #11.
       TTYI
       ASCIZ   "- List all accounts that have been "
       EVEN
       CRT     #12.
       TTYI
       ASCIZ   "PUSH"
       EVEN
       CRT     #11.
       TTYI
       ASCII   "ed."
       BYTE    15,15,0
       EVEN
       CRT     #12.
       JMP     EXIT

;
; Check for a valid switch
;
CHKSW:  CMPB    @A2,#'/         ; Switch requested?
       BNE     NOSW
       INC     A2              ; Bump command line pointer
       CMPB    @A2,#'L         ; Correct switch?
       BEQ     10$
       TYPECR  ?Illegal switch specified
       CRLF
       JMP     HELP
;
; The switch was correct...list accounts here
;
10$:    CALL    ACCLST          ; Display accounts loaded
       JMP     EXIT

;
; No switch was requested.  Verify that there is "enough room at the inn"
;
NOSW:   CLR     D0              ; Pre-clear D0
       MOVW    N.PPN(IMP),D0   ; Get current number of accounts loaded
       CMPW    D0,#M.NBR       ; Full, or is there room at the top?
       BLO     10$             ; Yes - Continue processing
                               ; push down stack, deleting oldest [CF-101]

                               ; [CF-101] adds push down of stack
       MOVL    #M.NBR-1,D0     ; Set up counter
       LEA     A1,STOR(IMP)    ; Get address of our first account location
       MOVL    A1,A4                   ; put address in A4 also
5$:     ADDW    #M.SIZ,A4               ; add entry size to A4
       MOVW    M.DEV(A4),M.DEV(A1)     ; copy down device
       MOVW    M.DRV(A4),M.DRV(A1)     ; copy down drive #
       MOVW    M.PPN(A4),M.PPN(A1)     ; copy down ppn
       MOVL    A4,A1                   ; raise lower pointer to upper
       SOB     D0,5$                   ; check for more to do
       MOVW    #M.NBR-1,N.PPN(IMP)     ; tell system we have room at the top!

10$:    BYP
       LIN                     ; Was a command line specified?
       BNE     GETLIN          ; Yes - Process account specified
       MOVW    JOBDEV(JOB),D0  ; Get our device name
       MOVW    JOBDRV(JOB),D1  ; Get our drive number
       MOVW    JOBUSR(JOB),D2  ; Get our PPN
       JMP     LODMEM          ;  and load the information into memory

;
; Begin processing account spec here
;
GETLIN: PUSH    A2              ; Save for later
       GETIMP  PPNSIZ,A2,EXIT  ; Allocate the DDB for lookup
       INIT    @A2             ; Initialize DDB for account
       MOV     A2,A3           ; Save for later
       MOVW    JOBDEV(JOB),DDB+D.DEV(A2) ; Store current device as default
       POP     A2              ; Restore command line pointer
       FSPEC   @A3             ; Get account specification into DDB
       JNE     HELP
       TSTW    DDB+D.DEV(A3)   ; Check to see that device was loaded correctly
       BNE     10$
       MOVW    JOBDEV(JOB),DDB+D.DEV(A3)

10$:    CMPW    DDB+D.DRV(A3),#177777 ; See if default drive number was given
       BNE     20$
       MOVW    JOBDRV(JOB),DDB+D.DRV(A3) ; Use current specification

20$:    MOVW    DDB+D.PPN(A3),D0; Get PPN
       BNE     30$             ; If PPN specified, continue
       MOVW    JOBUSR(JOB),DDB+D.PPN(A3) ; No PPN - use default

30$:    CLR     D0              ; Pre-clear D0
       MOV     A3,A2           ; Restore DDB pointer into A2
       MOVW    DDB+D.PPN(A2),D1; Get requested account
       CALL    $FNPPN          ; See if PPN exists
       BEQ     40$             ; Everything OK - Continue
       TYPECR  ?Account does not exist - cannot PUSH
       BR      EXIT

40$:    MOVW    DDB+D.DEV(A2),D0; Get specified device name
       MOVW    DDB+D.DRV(A2),D1; Get specified drive number
       MOVW    DDB+D.PPN(A2),D2; Get specified PPN

;
; Everything looks OK - smart user!  The following registers are set up:
; D0=Device Name, D1=Drive Number, D2=PPN
;
LODMEM: CLR     D3              ; Pre-clear D3
       MOVW    N.PPN(IMP),D3   ; Get last PPN location
       LEA     A1,STOR(IMP)    ; Get address of our first account location
       MOV     #M.SIZ,D4       ; Get module size
       MUL     D3,D4           ; Calculate the offset into memory module
       ADD     D3,A1           ;  for this load
       MOVW    D0,M.DEV(A1)    ; Load device name
       MOVW    D1,M.DRV(A1)    ; Load drive number
       MOVW    D2,M.PPN(A1)    ; Load PPN
       MOV     A1,A3           ; Store for ersatz check later
       INCW    N.PPN(IMP)      ; Bump account counter
       CRT     #11.
       TYPESP  Account:
       CRT     #12.
       CALL    SHOPPN          ; Display the account just loaded
       CRT     #11.
       TYPECR  < PUSHed>
       CRT     #12.
       CALL    CHKERS          ; Handle ersatz if applicable

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

;
; Begin subroutines here
;
; This subroutine sets up the listing of accounts within the user's memory
; module.  This routine is called via a switch (/L)
;
ACCLST: MOVW    N.PPN(IMP),D0   ; Get number of accounts to list
       JEQ     20$             ; No accounts - exit
       CRT     #11.            ; Set dim video
       TYPECR  The following accounts are PUSHed:
       CRT     #12.            ; Set regular video
       CRLF
       LEA     A1,STOR(IMP)    ; Index the first account

10$:    MOV     A1,A3           ; Store for ersatz check later on
       CALL    SHOPPN
       TAB
       CALL    CHKERS          ; Handle ersatz if necessary
       DEC     D0              ; Are we done yet?
       BEQ     30$             ; Yes - exit listing
       BR      10$

20$:    TYPECR  ?No accounts have been PUSHed

30$:    RTN                     ; Return to caller

;
; This subroutine displays the account pointed to by A1:
;
SHOPPN: LEA     A2,PBUF(IMP)    ; Address print buffer
       UNPACK                  ; To ASCII
       CLRB    @A2             ; Null at end
       TTYL    PBUF(IMP)       ; 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 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
10$:    CRLF
       RTN                             ; Back to caller

;
; This subroutine finds the ersatz name in ersatz table if applicable.  If
; found, return with Z-bit set and A2 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,A2               ; Index ersatz table
20$:    CMMW    EZ.PPN(A2),M.PPN(A3)    ; Does this entry have the same account?
       BNE     30$
       CMMW    EZ.DEV(A2),M.DEV(A3)    ; Does this entry have the same device?
       BNE     30$
       CMMW    EZ.UNT(A2),M.DRV(A3)    ; Does this entry have the same unit?
       BEQ     50$                     ; Yes - Zero flag set
30$:    ADDW    #EZ.SIZ,A2              ; Skip to next ersatz account
       TSTW    @A2                     ; 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 A2.
;
PRTERS: PUSH    A1                      ; Save pointer to account
       LEA     A1,EZ.NAM(A2)           ; Index ersatz name in table
       LEA     A2,PBUF(IMP)            ; 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(IMP)               ; print ersatz name it
       TYPE    <:>
       POP     A1                      ; Restore account pointer
       RTN

;
; Begin data definitions here
;
MOD:    RAD50   /ACCNTSPSH/
       EVEN

       END