;***************************************************************************;
;                                                                           ;
;                                    ERZ                                    ;
;                     Display ersatz names for a device                     ;
;                                                                           ;
;***************************************************************************;
;Copyright (C) 1986 by UltraSoft.  All Rights Reserved.
;
;Written by: David Pallmann
;
;ERZ displays the ersatz names of a device.  If no device is specified on
;the command line, all ersatz names are displayed.
;
;       .ERZ {Devn:} {/A} {/P}
;
;The /A switch displays the ersatz names in alphabetical order.
;The /P switch (page) waits for a RETURN every 24 lines.
;
;Edit History:
;1.0 17-Jun-86 created. /DFP

       VMAJOR=1
       VMINOR=0

       SEARCH  SYS
       SEARCH  SYSSYM

       MEM=A5                          ; base register
       LINE=D4                         ; line count
       COUNT=D5                        ; number of ersatz names output

       .OFINI
       .OFDEF  BUFFER,8.               ; RAD50-ASCII conversion buffer
       .OFDEF  DEV,2                   ; command line device code
       .OFDEF  DRV,2                   ; command line drive number
       .OFDEF  FLAGS,2                 ; flags:
               F$ALF=1                 ;  alphabetize
               F$PAG=2                 ;  page output
       .OFDEF  SAVERZ,EZ.SIZ           ; ersatz entry save area
       .OFSIZ  MEMSIZ

DEFINE  BITW    SRC,DST
       MOVW    DST,D7
       ANDW    SRC,D7
       ENDM

START:  PHDR    -1,PV$RSM,PH$REE!PH$REU ; program is reentrant, reusable
       GETIMP  MEMSIZ,MEM              ; allocate local memory
       MOV     ERSATZ,A4               ; point A4 to ersatz table
       CLR     COUNT                   ; clear output count
       CLR     LINE                    ; clear output line count

CHKTBL: TST     @A4                     ; is there an ersatz table?
       BNE     CMDLIN                  ;  yes
       TYPECR  %No ERSATZ table        ;  no
       EXIT                            ; exit

CMDLIN: BYP                             ; bypass leading spaces
       ALF                             ; device specified?
       BNE     SWITCH                  ;  no
       LEA     A1,DEV(MEM)             ; convert device code
       PACK                            ;  to RAD50
       GTDEC                           ; get drive number
       MOVW    D1,DRV(MEM)             ; store drive number
       INC     A2

SWITCH: BYP                             ; bypass leading white space
       CMMB    (A2)+,#'/               ; / present?
       BNE     PASS1                   ;  no
       CMMB    @A2,#'P                 ; /P?
       BEQ     SETPAG                  ;  yes
       CMMB    @A2,#'A                 ; /A?
       BNE     PASS1                   ;  no

SETALF: INC     A2                      ; bypass A
       ORW     #F$ALF,FLAGS(MEM)       ; set /A bit
       CALL    ALPHA                   ; alphabetize ersatz list
       BR      SWITCH                  ; process next switch

SETPAG: INC     A2                      ; bypass P
       ORW     #F$PAG,FLAGS(MEM)       ;  yes - set /P bit
       BR      SWITCH                  ; process next switch

;pass 1 - display ersatz device, drive, and PPN for next four table entries

PASS1:  MOV     A4,A0                   ; copy ersatz index to A0
       MOV     #4,D0                   ; set up loop reg. for 4 iterations
10$:    CTRLC   EXIT                    ; check for ^C
       TSTB    @A0                     ; end of table?
       BEQ     40$                     ;  yes - branch
       TSTW    DEV(MEM)                ; are we displaying all devices?
       BEQ     20$                     ;  yes - branch
       CMMW    DEV(MEM),EZ.DEV(A0)     ; is this the specified device?
       BNE     50$                     ;  no - go on to next entry
       CMMW    DRV(MEM),EZ.UNT(A0)     ; is this the specified drive?
       BNE     50$                     ;  no - go on to next entry
20$:    INCW    D5                      ; inc ersatz count
       LEA     A1,EZ.DEV(A0)           ; convert ersatz
       LEA     A2,BUFFER(MEM)          ;  device code
       UNPACK                          ;   to ASCII
       CLRB    @A2                     ; terminate string
       TTYL    BUFFER(MEM)             ; print ASCII device code
       CLR     D1                      ; clear D1
       MOVW    EZ.UNT(A0),D1           ; load into D1 ersatz drive number
       DCVT    0,OT$TRM                ; output as ASCII decimal
       TYPE    :[                      ; print colon and left bracket
       PRPPN   EZ.PPN(A0)              ; print ersatz PPN
       TYPE    ]                       ; type closing bracket
       TAB                             ; output a TAB
       ADD     #EZ.SIZ,A0              ; point A0 to the next table entry
       SOB     D0,10$                  ; loop 4 times
40$:    TSTW    D5                      ; have any ersatz names been output?
       JEQ     NOERZ                   ;  no
       CRLF                            ; print a newline
       BR      PASS2                   ; on to pass 2
50$:    ADD     #EZ.SIZ,A0              ; bypass non-matching ersatz entry
       BR      10$                     ; and process the next one

;pass 2 - display ersatz names

PASS2:  MOV     A4,A0                   ; copy ersatz index to A0
       MOV     #4,D0                   ; set up loop reg. for 4 iterations
10$:    CTRLC   EXIT                    ; check for ^C
       TSTB    @A0                     ; end of table?
       BEQ     30$                     ;  yes - branch
       TSTW    DEV(MEM)                ; are we displaying all devices?
       BEQ     20$                     ;  no - branch
       CMMW    DEV(MEM),EZ.DEV(A0)     ; is this the specified device?
       BNE     60$                     ;  no - go on to next entry
       CMMW    DRV(MEM),EZ.UNT(A0)     ; is this the specified drive?
       BNE     60$                     ;  no - go on to next entry
20$:    LEA     A1,EZ.NAM(A0)           ; convert ersatz
       LEA     A2,BUFFER(MEM)          ;  name
       UNPACK                          ;   to
       UNPACK                          ;    RAD50
       CLRB    @A2                     ; terminate string
       TTYL    BUFFER(MEM)             ; print ASCII ersatz name
       TAB                             ; output a TAB
       TAB                             ; make that two TABs
       ADD     #EZ.SIZ,A0              ; point to next entry
       SOB     D0,10$                  ; loop 4 times
30$:    CRLF                            ; print newline
       TSTB    @A0                     ; end of ersatz table?
       BEQ     DONE                    ;  yes - branch
       ADDW    #3,LINE                 ; update line count
       CMP     LINE,#24.               ; full screen?
       BLT     40$                     ;  no
       BITW    #F$PAG,FLAGS(MEM)       ; /P specified?
       BEQ     40$                     ;  no
       KBD     EXIT                    ; wait for RETURN
       CLR     LINE                    ; clear line count
       BR      50$
40$:    CRLF                            ; print another newline
50$:    ADD     #EZ.SIZ*4,A4            ; update ersatz index
       JMP     PASS1                   ; and output next line
60$:    ADD     #EZ.SIZ,A4              ; bypass non-matching entry
       ADD     #EZ.SIZ,A0              ;   "         "         "
       BR      10$                     ; on to the next one

NOERZ:  TYPECR  %No ersatz names for that device have been defined

DONE:   CRLF

EXIT:   EXIT                            ; exit

;ALPHA subroutine
;make copy of ersatz table and alphabetize it using simple bubble sort

ALPHA:  SAVE    A0-A3
       USRFRE  A1
       MOV     A1,A3
       MOV     A4,A0
10$:    MOV     #EZ.SIZ,D0
20$:    MOVB    (A0)+,(A1)+
       SOB     D0,20$
       TSTB    @A0
       BNE     10$
       CLRB    @A1

;sort the ersatz table we have just copied

SORT:   MOV     A3,A1

;check if current entry and current+1 are in order

CHECK:  TSTB    EZ.SIZ(A1)              ; end of table?
       BEQ     RETURN                  ;  yes - branch
       CMM     EZ.NAM(A1),EZ.NAM+EZ.SIZ(A1) ; entries in proper order?
       BLOS    NEXT                    ;       yes

;swap two entries so that they are in the correct order

SWAP:   PUSH    A1                      ; copy first entry to save area
       LEA     A0,SAVERZ(MEM)
       MOV     #EZ.SIZ,D0
10$:    MOVB    (A1)+,(A0)+
       SOB     D0,10$
       POP     A1

SWAP2:  PUSH    A1                      ; copy second entry over first
       LEA     A0,EZ.SIZ(A1)
       MOV     #EZ.SIZ,D0
10$:    MOVB    (A0)+,(A1)+
       SOB     D0,10$
       POP     A1

SWAP3:  PUSH    A1                      ; copy save area to second entry
       ADD     #EZ.SIZ,A1
       LEA     A0,SAVERZ(MEM)
       MOV     #EZ.SIZ,D0
10$:    MOVB    (A0)+,(A1)+
       SOB     D0,10$
       POP     A1

;after swapping, back-up an entry and continue with scan

BACKUP: SUB     #EZ.SIZ,A1              ; back-up an entry
       CMP     A1,A3                   ; are we before the 1st entry?
       BHIS    CHECK                   ;  no
       MOV     A3,A1                   ;  yes - fix pointer
       BR      CHECK                   ; and continue scan

;advance to next ersatz entry

NEXT:   ADD     #EZ.SIZ,A1              ; advance to next table entry
       BR      CHECK                   ; and continue scan

;return from subroutine

RETURN: MOV     A3,A4                   ; point A4 to sorted ersatz table
       REST    A0-A3                   ; restore registers
       RTN                             ; return

       END