[comp.os.vms] Virtual File Editor

PORTIA@ENGVAX.SCG.HAC.COM (Portia 616-2635) (07/25/87)

$ show default
$ check_sum = 1533430152
$ write sys$output "Creating FILEHDLR.MAR"
$ create FILEHDLR.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .TITLE  FILEHDLR File manipulation routines

        .ENABLE SUPPRESSION

        .LIBRARY  'SYS$LIBRARY:LIB.MLB'
        .LIBRARY  'VFELIB'

        $ATRDEF
        $DCDEF
        $DEVDEF
        $DVIDEF
        $FABDEF
        $FATDEF
        $FIBDEF
        $IODEF
        $MTDEF
        $NAMDEF

        .PSECT  CODE,EXE,NOWRT
        .PAGE
        .SBTTL  GETFILE - Get file name and access it
GETFILE::
        CLRL    FLFLGS
        TSTW    DESC
        BEQL    150$
        BSBW    FPARSE
        BLBC    R0,200$
        TSTL    SETMASK
        BEQL    70$
        CLRL    R1
        BSBW    SETCMD
70$:
        TSTW    FDESC
        BGTR    400$
        BRB     150$
100$:
        CLRL    FLFLGS
150$:
        INPUT   FNQ,FNQ+8,#80,FNAME
        MOVAL   FNAME,DESC+4
        MOVW    TSTATUS+2,DESC
        CLRB    INITFLG
        BSBW    FPARSE
        BLBC    R0,200$
        TSTW    FDESC
        BGTR    400$
200$:
        TSTB    OPNFLG
        BEQL    100$
        BRW     900$
400$:
        CLRB    INITFLG
        BSBW    RELFILE
        CLRB    LOGFLG
        CLRB    SEQFLG
        CLRB    TAPFLG
        MOVL    #IO$_READVBLK,READFNC
        MOVL    #IO$_WRITEVBLK,WRITEFNC
        MOVL    #1,LOBLK
        MOVAL   FABBLK,R2
        MOVB    FDESC,FAB$B_FNS(R2)
        MOVL    FDESC+4,FAB$L_FNA(R2)
        $PARSE  FAB=FABBLK
        BLBS    R0,500$
        CMPL    R0,#RMS$_DNF
        BEQL    500$
        BRW     780$
500$:
        MOVAL   NAMBLK,R6
;
;       This is an unorthodox method to determine if only a device name
;       is specified, but it seems to work.  If the bit definitions
;       of NAM$L_FNB are ever changed, this instruction may require
;       modification.
;
        CMPW    #NAM$M_EXP_DEV,NAM$L_FNB(R6)
;
        BNEQ    520$
        INCB    LOGFLG
        MOVZBL  NAM$B_DEV(R6),CURNAM
        MOVC3   CURNAM,@NAM$L_DEV(R6),CURNAM+2
        ADDW2   #2,CURNAM
        BRB     540$
520$:
        BLBS    R0,540$
        BRW     780$
540$:
        BITL    #NAM$M_WILDCARD,NAM$L_FNB(R6)
        BEQL    550$
        MOVL    #RMS$_FNM,R0
        BRW     780$
550$:
        BITL    #NAM$M_NODE,NAM$L_FNB(R6)
        BEQL    570$
        OUTMSGC NNWMSG
        BRW     100$
570$:
        MOVB    NAM$B_DEV(R6),DISKD
        MOVL    NAM$L_DEV(R6),DISKD+4
        $ASSIGN_S  CHAN=DD,DEVNAM=DISKD
        BLBS    R0,600$
        BRW     780$
600$:
        MOVB    #1,ASSFLG
        $GETDVI_S  EFN=#0,CHAN=DD,ITMLST=DEVLST,IOSB=FSTATUS
        BLBS    R0,610$
        BRW     780$
610$:
        $WAITFR_S  EFN=#0
        BSBW    IOSTAT
        BLBS    R0,620$
        BRW     780$
620$:
        CMPL    #DC$_DISK,DEVCLS
        BNEQ    625$
        BRW     680$
625$:
        CMPL    #DC$_TAPE,DEVCLS
        BEQL    630$
        OUTMSGC ICDMSG
        BRW     790$
630$:
        TSTB    LOGFLG
        BNEQ    640$
        OUTMSGC TAP1MSG
        BRW     790$
640$:
        BITL    #DEV$M_MNT,DEVCHR
        BEQL    645$
        BITL    #DEV$M_FOR,DEVCHR
        BNEQ    650$
645$:
        OUTMSGC TAP2MSG
        BRW     790$
650$:
        TSTW    OVRWRT
        BEQL    655$
        OUTMSGC TAP3MSG
        BRW     790$
655$:
        MOVB    #1,TAPFLG
        MOVL    #IO$_READLBLK,READFNC
        CLRL    LOBLK
        MOVL    #9999999,HIBLK
        MOVL    #9999999,EFBLK
        MOVC5   #0,FILBLK,#^XFF,#1024,FILBLK
        TSTB    POSFLG
        BNEQ    665$
        TSTB    NOREW
        BNEQ    660$
        BSBW    REWIND
        BLBS    R0,670$
        BRW     790$
660$:
        OUTMSGC TAP4MSG
        CLRL    CURFIL
        MNEGL   #1,CURBLK
        MOVL    #1,PARA1
        BRB     668$
665$:
        MOVL    #1,CURFIL
        BSBW    SETPOS
        CLRL    PARA1
668$:
        CLRB    CUREOF
        MOVB    #1,PRTEOF
        BSBW    READTAPE
        BLBS    R0,670$
        BRW     900$
670$:
        BRW     870$
680$:
        CMPL    BLKSIZ,#512
        BEQL    681$
        OUTMSGC NSBMSG
        BRW     790$
681$:
        TSTB    LOGFLG
        BNEQ    682$
        BRW     700$
682$:
        MOVL    #IO$_READLBLK,READFNC
        CLRL    LOBLK
        SUBL3   #1,MAXBLK,HIBLK
        MOVL    HIBLK,EFBLK
        MOVL    #511,FFBYTE
        TSTB    WRTFLG
        BNEQ    685$
        BRW     840$
685$:
        BITL    #DEV$M_FOR,DEVCHR
        BEQL    690$
        MOVL    #IO$_WRITELBLK,WRITEFNC
        OUTMSGC WWED
        BRW     850$
690$:
        OUTMSGC NWLMSG
        BRW     790$
700$:
        $SEARCH FAB=FABBLK
        BLBS    R0,720$
        BRW     780$
720$:
        MOVL    NAM$W_FID(R6),FIB+FIB$W_FID
        MOVW    NAM$W_FID+4(R6),FIB+FIB$W_FID+4
        CLRL    FIB+FIB$L_ACCTL
        TSTB    WRTFLG
        BEQL    750$
        MOVL    #FIB$M_WRITE,FIB+FIB$L_ACCTL
750$:
        $QIOW_S CHAN=DD,FUNC=#IO$_ACCESS!IO$M_ACCESS, -
                IOSB=FSTATUS,P1=FIBD,P5=#ATRLST
        BSBW    IOSTAT
        BLBS    R0,800$
        CMPW    R0,#SS$_ACCONFLICT
        BNEQ    780$
        TSTB    OVRFLG
        BEQL    780$
        MOVL    #FIB$M_NOLOCK,FIB+FIB$L_ACCTL
        $QIOW_S CHAN=DD,FUNC=#IO$_ACCESS!IO$M_ACCESS, -
                IOSB=FSTATUS,P1=FIBD,P5=#ATRLST
        BSBW    IOSTAT
        BLBC    R0,780$
        MOVL    #SS$_ACCONFLICT,R0
        BSBW    ERROUT
        BRB     800$
780$:
        BSBW    ERROUT
790$:
        BRW     100$
800$:
        MOVB    #1,ACCFLG
        MOVW    RECATTR+FAT$W_HIBLKL,HIBLK
        MOVW    RECATTR+FAT$W_HIBLKH,HIBLK+2
        TSTL    HIBLK
        BNEQ    810$
        OUTMSGC NEF
        BRW     100$
810$:
        MOVZBL  NAM$B_RSL(R6),CURNAM
        MOVC3   CURNAM,@NAM$L_RSA(R6),CURNAM+2
        ADDW2   #2,CURNAM
        MOVW    RECATTR+FAT$W_EFBLKL,EFBLK
        MOVW    RECATTR+FAT$W_EFBLKH,EFBLK+2
        CVTWL   RECATTR+FAT$W_FFBYTE,FFBYTE
        CVTWL   RECATTR+FAT$W_RSIZE,RSIZE
        CMPZV   #FAT$V_FILEORG,#4,RECATTR+FAT$B_RTYPE,#FAT$C_SEQUENTIAL
        BNEQ    815$
        INCB    SEQFLG
        TSTL    RSIZE
        BNEQ    812$
        MOVL    #140,RSIZE
812$:
        TSTL    FFBYTE
        BNEQ    815$
        CMPL    EFBLK,#1
        BGTR    815$
        MOVL    HIBLK,EFBLK
        MOVL    #511,FFBYTE
815$:
        CLRB    VFLAG
        CLRL    VFCSIZE
        CMPZV   #FAT$V_RTYPE,#4,RECATTR+FAT$B_RTYPE,#FAT$C_VARIABLE
        BEQL    820$
        CMPZV   #FAT$V_RTYPE,#4,RECATTR+FAT$B_RTYPE,#FAT$C_VFC
        BNEQ    830$
        CVTBL   RECATTR+FAT$B_VFCSIZE,VFCSIZE
820$:
        INCB    VFLAG
830$:
        EXTZV   #FAT$V_NOSPAN,#1,RECATTR+FAT$B_RATTRIB,NOSPNFLG
        TSTB    WRTFLG
        BEQL    840$
        OUTMSGC WWE
        BRB     850$
840$:
        OUTMSG  #ROML,ROM
850$:
        CLRL    CURBLK
        MOVL    LOBLK,PARA1
        BSBW    READDISK
        BLBS    R0,870$
        CMPL    R0,#SS$_NOPRIV
        BNEQ    900$
        BRW     100$
870$:
        BSBW    BLOCK
900$:
        MOVB    #1,OPNFLG
        RSB

        .SBTTL  RELFILE - Deaccess file
RELFILE::
        TSTB    ACCFLG
        BEQL    150$
        $QIOW_S CHAN=DD,FUNC=#IO$_DEACCESS,P1=FIBD
        BLBS    R0,150$
        BRW     ERREXT
150$:
        CLRB    ACCFLG
        TSTB    ASSFLG
        BEQL    170$
        $DASSGN_S  CHAN=DD
        BLBS    R0,170$
        BRW     ERREXT
170$:
        CLRB    ASSFLG
        CLRB    OPNFLG
        RSB
        .PAGE
        .SBTTL  TOP - Go to top of file
TOP::
        TSTB    TAPFLG
        BNEQ    100$
        MOVL    LOBLK,PARA1
        BSBW    READDISK
        BRB     200$
100$:
        TSTB    CUREOF
        BNEQ    200$
        MNEGL   #9999999,PARA1
        CLRB    PRTEOF
        BSBW    READTAPE
200$:
        RSB

        .SBTTL  NEXT - Go to next block
NEXT::
        TSTB    TAPFLG
        BNEQ    200$
        MOVL    BUFFCT,R1
        TSTL    PARA1
        BLEQ    100$
        DIVL3   #512,CURBCT,R1
100$:
        MULL2   R1,PARA1
        ADDL2   CURBLK,PARA1
        BSBW    READDISK
        BRB     300$
200$:
        MOVB    #1,PRTEOF
        BSBW    READTAPE
300$:
        RSB
        .PAGE
        .SBTTL  EOF - Position at end-of-file block
EOF::
        TSTB    TAPFLG
        BEQL    30$
        BRW     100$
30$:
        MOVL    #100,OUTDSC
        MOVAL   EFBLKM,DESC+4
        TSTB    HEXFLG
        BEQL    50$
        MOVAL   EFBLKMX,DESC+4
50$:
        $FAO_S  CTRSTR=@DESC+4,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=EFBLK,P2=FFBYTE
        OUTMSG  OUTDSC,OUT_BUFF
        MOVL    EFBLK,PARA1
        CMPL    PARA1,HIBLK
        BLEQ    80$
        MOVL    HIBLK,PARA1
80$:
        BSBW    READDISK
        BRB     200$
100$:
        BSBW    LAST
200$:
        RSB

        .SBTTL  LAST - Position at last block in file
LAST::
        TSTB    TAPFLG
        BNEQ    100$
        MOVL    HIBLK,PARA1
        BSBW    READDISK
        BRB     200$
100$:
        MOVL    #9999999,PARA1
        CLRB    PRTEOF
        BSBW    READTAPE
        CMPL    R0,#SS$_ENDOFFILE
        BNEQ    200$
        MNEGL   #1,PARA1
        MOVB    #1,PRTEOF
        BSBW    READTAPE
200$:
        RSB
        .PAGE
        .SBTTL  READ - Read data
READ::
        TSTB    TAPFLG
        BNEQ    180$
        CMPL    PARA1,HIBLK
        BLEQ    150$
        TSTB    LOGFLG
        BNEQ    130$
        BSBW    READDISK
        BLBS    R0,400$
130$:
        MOVL    HIBLK,PARA1
150$:
        BSBW    READDISK
        BRB     400$
180$:
        TSTL    CURBLK
        BGEQ    200$
        TSTL    PARA1
        BLSS    200$
        OUTMSGC NOABS
        CLRL    R0
        BRB     400$
200$:
        SUBL2   CURBLK,PARA1
        MOVB    #1,PRTEOF
        BSBW    READTAPE
400$:
        RSB

        .SBTTL  READINT - Internal read
;
; R1=Block number, R2=Byte count
;
READINT::
        ADDL3   #BUFF,CURBCT,READLOC
        TSTB    TAPFLG
        BNEQ    100$
        $QIOW_S CHAN=DD,FUNC=READFNC,IOSB=FSTATUS,-
                P1=@READLOC,P2=R2,P3=R1
        BRB     200$
100$:
        $QIOW_S CHAN=DD,FUNC=#IO$_READLBLK,IOSB=FSTATUS,-
                P1=@READLOC,P2=#MAXBCT
200$:
        BSBW    IOSTAT
        MOVZWL  FSTATUS+2,NXTBCT
        RSB
        .PAGE
        .SBTTL  READDISK - Read disk blk, PARA1=address
READDISK:
        MOVL    BUFFCT,R1
        CMPL    PARA1,LOBLK
        BGEQ    100$
        MOVL    LOBLK,PARA1
        BRB     200$
100$:
        TSTB    LOGFLG
        BEQL    200$
        SUBL3   PARA1,HIBLK,R1
        BGEQ    150$
        MOVL    #SS$_ENDOFFILE,R0
        CLRL    R1
        BRB     250$
150$:
        INCL    R1
        CMPL    R1,BUFFCT
        BLEQ    200$
        MOVL    BUFFCT,R1
200$:
        MULL2   #512,R1
        $QIOW_S CHAN=DD,FUNC=READFNC,IOSB=FSTATUS,-
                P1=BUFF,P2=R1,P3=PARA1
        DIVL3   #512,FSTATUS+2,R1
        BSBW    IOSTAT
        BLBS    R0,300$
        TSTL    R1
        BEQL    250$
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    300$
250$:
        MOVL    R0,SVSTAT
        BSBW    ERROUT
        TSTL    R1
        BGTR    300$
        MOVL    SVSTAT,R0
        CMPL    PARA1,HIBLK
        BLEQ    280$
        BRW     400$
280$:
        MOVL    #512,CURBCT
        BRB     350$
300$:
        MOVL    #1,R0
        TSTL    R1
        BGTR    310$
        MOVL    #1,R1
310$:
        MULL3   #512,R1,CURBCT
        DECL    R1
        ADDL2   PARA1,R1
        CMPL    R1,HIBLK
        BLEQ    350$
        MOVL    R1,HIBLK
        MOVL    R1,EFBLK
        MOVL    #511,FFBYTE
350$:
        MOVL    PARA1,CURBLK
        CLRL    LPTR
        MNEGL   #1,RECPTR
400$:
        RSB

        .SBTTL  WRITEDISK - Write work buffer to disk
WRITEDISK::
        TSTB    WRTFLG
        BNEQ    100$
        OUTMSG  #ROMWL,ROM
        BRB     900$
100$:
        $QIOW_S CHAN=DD,FUNC=WRITEFNC,IOSB=FSTATUS,-
                P1=BUFF,P2=CURBCT,P3=CURBLK
        BSBW    IOSTAT
        BLBS    R0,200$
        BSBW    ERROUT
        BRB     900$
200$:
        OUTMSGC RDY
900$:

        RSB
        .PAGE
        .SBTTL  REWIND - Rewind a tape
REWIND::
        TSTB    TAPFLG
        BNEQ    100$
        OUTMSGC TAPONLY
        BRB     300$
100$:
        $QIOW_S CHAN=DD,FUNC=#IO$_REWIND,IOSB=FSTATUS
        BSBW    IOSTAT
        BLBS    R0,200$
        BSBW    ERROUT
        CLRL    R0
        BRB     300$
200$:
        MOVL    #1,CURFIL
        CLRL    CURBLK
        CLRB    CUREOF
        MOVL    #1,PARA1
        MOVB    #1,PRTEOF
        BSBW    READTAPE
        MOVL    #1,R0
300$:
        RSB

        .SBTTL  BACKSPACE - Move a tape back one block or EOF
BACKSPACE::
        TSTB    TAPFLG
        BEQL    100$
        BITL    #MT$M_LOST,FSTATUS+4
        BNEQ    100$
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPRECORD,IOSB=FSTATUS,-
                P1=-1
        BSBW    IOSTAT
        BLBS    R0,100$
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    100$
        BSBW    ERROUT
100$:
        RSB
        .PAGE
        .SBTTL  MOVE - Move over 1 or more EOF marks
MOVE::
        TSTB    TAPFLG
        BNEQ    50$
        OUTMSGC TAPONLY
        BRW     900$
50$:
        MOVL    PARA1,R2
        BGTR    100$
        BEQL    70$
        BRW     200$
70$:
        BRW     900$
100$:
        TSTB    STOP
        BNEQ    140$
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPFILE,IOSB=FSTATUS,-
                P1=1
        BSBW    IOSTAT
        BLBS    R0,120$
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    120$
        BSBW    ERROUT
        CLRL    CURBCT
        BRB     140$
120$:
        INCL    CURFIL
        CLRL    CURBLK
        CLRL    CURBCT
        MOVB    #1,CUREOF
        SOBGTR  R2,100$
140$:
        BRW     900$
200$:
        TSTB    STOP
        BEQL    220$
        BRW     900$
220$:
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPFILE,IOSB=FSTATUS,-
                P1=-1
        BSBW    IOSTAT
        BLBS    R0,240$
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    240$
        BSBW    ERROUT
        BRB     250$
240$:
        BITL    #MT$M_BOT,FSTATUS+4
        BEQL    270$
        OUTMSGC BOTMSG
        CLRL    CURBLK
        MOVB    #1,CUREOF
250$:
        CLRL    CURBCT
        BRW     900$
270$:
        DECL    CURFIL
        MOVZBL  CURFIL,R1
        MOVL    FILBLK[R1],CURBLK
        CLRB    CUREOF
        CLRL    CURBCT
        AOBLSS  #0,R2,300$
        BRB     400$
300$:
        BRW     200$
400$:
        CLRL    PARA1
        CLRB    PRTEOF
        BSBW    READTAPE
900$:
        RSB
        .PAGE
        .SBTTL  READTAPE - Read tape blk, PARA1 = offset
READTAPE:
        CMPL    PARA1,#1
        BGTR    100$
        BEQL    50$
        BRW     200$
50$:
        BRW     510$
100$:
        SUBL3   #1,PARA1,SKIPTOT
110$:
        MOVL    SKIPTOT,SKIPCT
        SUBL2   SKPINC,SKIPTOT
        BLEQ    120$
        MOVL    SKPINC,SKIPCT
120$:
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPRECORD,IOSB=FSTATUS,-
                P1=@SKIPCT
        BSBW    IOSTAT
        MOVZWL  FSTATUS+2,R1
        BLBC    R0,140$
        ADDL2   R1,CURBLK
        TSTL    SKIPTOT
        BLEQ    130$
        TSTB    STOP
        BEQL    110$
130$:
        BRW     500$
140$:
        TSTB    BUGFLG
        BNEQ    145$
        DECL    R1
        BLEQ    145$
        ADDL2   R1,CURBLK
145$:
        CMPL    R0,#SS$_ENDOFFILE
        BNEQ    180$
        TSTB    BUGFLG
        BEQL    150$
        CMPL    SKIPCT,#1
        BGTR    160$
150$:
        MOVZBL  CURFIL,R1
        MOVL    CURBLK,FILBLK[R1]
160$:
        BRW     600$
180$:
        BRW     900$
200$:
        TSTB    CUREOF
        BNEQ    220$
        SUBL3   #1,PARA1,SKIPTOT
        BRW     300$
220$:
        TSTL    PARA1
        BNEQ    230$
        MOVL    #1,R0
        BRW     950$
230$:
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPRECORD,IOSB=FSTATUS,-
                P1=-1
        BSBW    IOSTAT
        BLBC    R0,250$
        BITL    #MT$M_BOT,FSTATUS+4
        BEQL    240$
        BRW     400$
240$:
        DECL    CURBLK
        BRB     270$
250$:
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    260$
        BRW     450$
260$:
        DECL    CURFIL
        MOVZBL  CURFIL,R1
        MOVL    FILBLK[R1],CURBLK
270$:
        CLRB    CUREOF
        MOVL    PARA1,SKIPTOT
300$:
        MOVL    SKIPTOT,SKIPCT
        ADDL2   #50,SKIPTOT
        BGEQ    320$
        MNEGL   #50,SKIPCT
320$:
        $QIOW_S CHAN=DD,FUNC=#IO$_SKIPRECORD,IOSB=FSTATUS,-
                P1=@SKIPCT
        BSBW    IOSTAT
        BLBC    R0,350$
        BITL    #MT$M_BOT,FSTATUS+4
        BNEQ    400$
        MOVZWL  FSTATUS+2,R1
        SUBL2   R1,CURBLK
        TSTL    SKIPTOT
        BGEQ    330$
        TSTB    STOP
        BEQL    300$
330$:
        BRW     500$
350$:
        CMPL    R0,#SS$_ENDOFFILE
        BNEQ    450$
        BITL    #MT$M_BOT,FSTATUS+4
        BNEQ    400$
        DECL    CURFIL
        MOVZBL  CURFIL,R1
        MOVL    FILBLK[R1],CURBLK
        BRW     500$
400$:
        OUTMSGC BOTMSG
        CLRL    CURBLK
        MOVB    #1,CUREOF
        CLRL    CURBCT
        MOVL    #SS$_ENDOFFILE,R0
        BRW     950$
450$:
        MOVZWL  FSTATUS+2,R1
        DECL    R1
        BGTR    460$
        BRW     900$
460$:
        SUBL2   R1,CURBLK
        CLRB    CUREOF
        BRW     900$
500$:
        CLRL    CURBCT
510$:
        $QIOW_S CHAN=DD,FUNC=#IO$_READLBLK,IOSB=FSTATUS,-
                P1=BUFF,P2=#MAXBCT
        BSBW    IOSTAT
        MOVZWL  FSTATUS+2,CURBCT
        BLBC    R0,520$
        INCL    CURBLK
        CLRB    CUREOF
        BRW     950$
520$:
        CMPL    R0,#SS$_ENDOFFILE
        BNEQ    800$
        MOVZBL  CURFIL,R1
        MOVL    CURBLK,FILBLK[R1]
600$:
        TSTB    PRTEOF
        BEQL    620$
        OUTMSGC EOFMSG
620$:
        CLRL    CURBCT
        CLRL    CURBLK
        INCL    CURFIL
        MOVB    #1,CUREOF
        MOVL    #SS$_ENDOFFILE,R0
        BRB     950$
800$:
        TSTL    CURBCT
        BGTR    850$
        BITL    #MT$M_LOST,FSTATUS+4
        BNEQ    900$
850$:
        INCL    CURBLK
900$:
        MOVL    R0,SVSTAT
        BSBW    ERROUT
        MOVL    SVSTAT,R0
950$:
        CLRL    LPTR
        MNEGL   #1,RECPTR
        RSB
        .PAGE
        .SBTTL  SHOFILE - Display current file and block
SHOFILE::
        SUBW3   #2,CURNAM,DESC
        MOVAL   CURNAM+2,DESC+4
        MOVL    #150,OUTDSC
        TSTB    LOGFLG
        BNEQ    100$
        $FAO_S  CTRSTR=WHRMSG,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=#DESC,P2=CURBLK
        BRB     200$
100$:
        $FAO_S  CTRSTR=WHDMSG,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=#DESC,P2=CURBLK
200$:
        OUTMSG  OUTDSC,OUT_BUFF
        RSB

IOSTAT:
        BLBC    R0,100$
        MOVZWL  FSTATUS,R0
100$:
        RSB

        .SBTTL  SETPOS - Set file, block pos for tape
SETPOS::
        TSTB    TAPFLG
        BNEQ    100$
        OUTMSGC TAPONLY
        BRB     200$
100$:
        MOVL    POSBLK,CURBLK
        MOVZBL  CURFIL,R1
        MOVL    #^XFFFFFFFF,FILBLK[R1]
        CMPL    POSFIL,CURFIL
        BEQL    200$
        MOVL    POSFIL,CURFIL
        MOVC5   #0,FILBLK,#^XFF,#1024,FILBLK
200$:
        RSB
        .PAGE
        .SBTTL  Data definitions

        .PSECT  DATA,WRT,NOEXE,LONG

DISKD:  .WORD   0
        .WORD   ^X010E
        .LONG   0
DD:     .BLKW   1

FSTATUS: .BLKL 2

FDESC:: .WORD   0
        .WORD   ^X010E
        .LONG   0

FNAME:: .BLKB   80
FNQ::   .ASCID  /File name? /

NNWMSG: .ASCIC  /Network operation is unsupported at this time./

ICDMSG: .ASCIC  /Incorrect device type - must be disk or tape./

TAP1MSG: .ASCIC /File-structured operation is unsupported for tape./

TAP2MSG: .ASCIC /Tape is not mounted or is not mounted FOREIGN./

TAP3MSG: .ASCIC "Can not specify /OVER or /WRITE for tape operation."

TAP4MSG: .ASCIC /*Tape position is unknown*/

NSBMSG: .ASCIC  /Disk device has nonstandard block size - can not edit./

NWLMSG: .ASCIC  "Can not specify /WRITE for XQP-device logical I/O."

WWE:    .ASCIC  /File accessed with write enabled/

WWED:   .ASCIC  /Device accessed with write enabled/

ROM:    .ASCII  /Read-only mode/
ROML=.-ROM
        .ASCII  /; WRITE not allowed/
ROMWL=.-ROM

NEF:    .ASCIC  /Can not edit an empty file/

RDY:    .ASCIC  /Ready/

NOABS:  .ASCIC  /Absolute addresses unknown within this file./

TAPONLY: .ASCIC /This command can only be used with a tape device./

BOTMSG: .ASCIC  /**BOT**/

EOFMSG: .ASCIC  /**EOF**/

EFBLKM: .ASCID  /EOF block=!UL, EOF byte=!UL/
EFBLKMX: .ASCID /EOF block=!UL, EOF byte=!4XL/

WHRMSG: .ASCID  /Editing file !AS - Block !UL/
WHDMSG: .ASCID  /Editing device !AS - Block !UL/

        .ALIGN  LONG

FABBLK: $FAB    FOP=NAM,NAM=NAMBLK
NAMBLK: $NAM    RSA=RESSTR,RSS=NAM$C_MAXRSS,-
                ESA=EXPSTR,ESS=NAM$C_MAXRSS
RESSTR: .BLKB   NAM$C_MAXRSS
EXPSTR: .BLKB   NAM$C_MAXRSS

CURNAM:: .WORD  0
        .BLKB   NAM$C_MAXRSS

CURBLK:: .LONG  1
LOBLK:  .LONG   1
HIBLK:: .LONG   0
EFBLK:: .LONG   0
FFBYTE:: .LONG  0
CURFIL:: .LONG  0
CURBCT:: .LONG  512
NXTBCT:: .LONG  0
BUFFCT:: .LONG  1
NBUFCT:: .LONG  0
CUREOF: .BYTE   0
PRTEOF: .BYTE   1
SEQFLG:: .BYTE  0
VFLAG:: .BYTE   0
RSIZE:: .LONG   0
VFCSIZE:: .LONG 0
NOSPNFLG:: .LONG 0
SVSTAT: .LONG   0

ASSFLG: .BYTE   0

ACCFLG: .BYTE   0

OPNFLG: .BYTE   0

TAPFLG:: .BYTE  0

LOGFLG: .BYTE   0

READFNC:  .LONG IO$_READVBLK
WRITEFNC: .LONG IO$_WRITEVBLK

READLOC: .LONG  0
SKIPTOT: .LONG  0
SKIPCT: .LONG   0

FLFLGS:
OVRWRT::
OVRFLG:: .BYTE  0
WRTFLG:: .BYTE  0
NOREW:: .BYTE   0
POSFLG:: .BYTE  0

POSFIL:: .LONG  0
POSBLK:: .LONG  0

BUGFLG:: .BYTE  0
SKPINC:: .LONG  50

DEVLST: .WORD   4
        .WORD   DVI$_DEVCHAR
        .ADDRESS DEVCHR
        .LONG   0
        .WORD   4
        .WORD   DVI$_DEVCLASS
        .ADDRESS DEVCLS
        .LONG   0
        .WORD   4
        .WORD   DVI$_DEVBUFSIZ
        .ADDRESS BLKSIZ
        .LONG   0
        .WORD   4
        .WORD   DVI$_MAXBLOCK
        .ADDRESS MAXBLK
        .LONG   0
        .LONG   0
DEVCHR: .LONG   0
DEVCLS: .LONG   0
BLKSIZ: .LONG   0
MAXBLK: .LONG   0
FIB:    .BLKL   12
FIBD:   .LONG   12
        .LONG   FIB
ATRLST: .WORD   ATR$S_RECATTR
        .WORD   ATR$C_RECATTR
        .ADDRESS  RECATTR
        .LONG   0
RECATTR:  .BLKB ATR$S_RECATTR

        .ALIGN  LONG

FILBLK: .BLKL   256

        .END
$*$*EOD*$*$
$ checksum FILEHDLR.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ check_sum = 1869233584
$ write sys$output "Creating TERMHDLR.MAR"
$ create TERMHDLR.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .TITLE TERMHDLR Terminal and log file I/O routines

        .ENABLE SUPPRESSION

        .LIBRARY  'VFELIB'

        $DCDEF
        $DVIDEF
        $FABDEF
        $IODEF
        $NAMDEF
        $RABDEF

        .PSECT  CODE,EXE,NOWRT
        .PAGE
        .SBTTL  TINIT - Intitialize terminal I/O
TINIT::
        $ASSIGN_S  DEVNAM=TERM,CHAN=TT
        BLBC    R0,100$
        $QIOW_S CHAN=TT,FUNC=#IO$_SETMODE!IO$M_CTRLCAST,-
                EFN=#1,P1=CTRLCAST,P3=#3
        BLBS    R0,200$
100$:
        CLRW    TERMFLGS
        BRW     800$
200$:
        $GETDVI_S  EFN=#0,DEVNAM=SYSIN,ITMLST=GETCLS,IOSB=TSTATUS
        BLBS    R0,220$
        BRW     900$
220$:
        $WAITFR_S  EFN=#0
        MOVZWL  TSTATUS,R0
        BLBS    R0,240$
        BRW     900$
240$:
        CMPL    #DC$_TERM,IOCLASS
        BEQL    300$
        CLRB    TERMIN
300$:
        $GETDVI_S  EFN=#0,DEVNAM=SYSOUT,ITMLST=GETCLS,IOSB=TSTATUS
        BLBS    R0,320$
        BRB     900$
320$:
        $WAITFR_S  EFN=#0
        MOVZWL  TSTATUS,R0
        BLBS    R0,340$
        BRB     900$
340$:
        CMPL    #DC$_TERM,IOCLASS
        BEQL    400$
        CLRB    TERMOUT
        BRB     800$
400$:
        $QIOW_S CHAN=TT,FUNC=#IO$_SENSEMODE,IOSB=TSTATUS,-
                P1=MODBUF,P2=#8
        BLBC    R0,900$
        MOVZWL  TSTATUS,R0
        BLBC    R0,900$
        MOVZWL  TT_WID,TERMWD
800$:
        MOVL    #1,R0
900$:
        RSB
        .PAGE
        .SBTTL  LOGON - Turn on logging or switch log file
LOGON::
        BSBW    LOGOFF
        MOVB    DESC,LOGFAB+FAB$B_FNS
        MOVL    DESC+4,LOGFAB+FAB$L_FNA
        $CREATE FAB=LOGFAB
        BLBS    R0,100$
        BSBW    ERROUT
        BRW     900$
100$:
        $CONNECT  RAB=LOGRAB
        BLBS    R0,200$
        BRW     ERREXT
200$:
        CLRB    NOLOG
900$:
        RSB

        .SBTTL  LOGOFF - Turn off logging
LOGOFF::
        TSTB    NOLOG
        BNEQ    900$
        $CLOSE  FAB=LOGFAB
        BLBS    R0,900$
        BRW     ERREXT
900$:
        MOVB    #1,NOLOG
        RSB

        .SBTTL  SHOLOG - Display log file status
SHOLOG::
        TSTB    NOLOG
        BEQL    100$
        OUTMSGC NLGMSG
        BRB     900$
100$:
        MOVL    #100,OUTDSC
        MOVAL   LOGNBK,R6
        MOVB    NAM$B_RSL(R6),DESC
        MOVL    NAM$L_RSA(R6),DESC+4
        $FAO_S  CTRSTR=LOGMSG,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=#DESC
        OUTMSG  OUTDSC,OUT_BUFF
900$:
        RSB
        .PAGE
        .SBTTL  CTRLCAST - Handle user interrupts
CTRLCAST:
        .WORD   0
        $QIOW_S CHAN=TT,FUNC=#IO$_SETMODE!IO$M_CTRLCAST,-
                EFN=#1,P1=CTRLCAST,P3=#3
        BLBS    R0,100$
        BRW     ERREXT
100$:
        MOVB    #1,STOP
        RET

        .SBTTL  SETWID - Set terminal width (80/132)
SETWID::
        CMPL    NEWWID,TERMWD
        BNEQ    100$
        BRW     500$
100$:
        CMPL    NEWWID,#80
        BGTR    200$
        MOVL    #80,R2
        MOVAL   SETLOW,DESC+4
        BRB     300$
200$:
        MOVL    #132,R2
        MOVAL   SETHIGH,DESC+4
300$:
        BLBC    R1,400$
        MOVL    R2,NEWWID
400$:
        MOVL    NEWWID,TERMWD
        TSTB    TERMOUT
        BEQL    500$
        MOVW    TERMWD,TT_WID
        $QIOW_S CHAN=TT,FUNC=#IO$_SETMODE,P1=MODBUF,P2=#8
        BLBC    R0,900$
        $QIOW_S CHAN=TT,FUNC=#IO$_WRITEVBLK,P1=@DESC+4,P2=#5
        BLBC    R0,900$
500$:
        MOVL    #1,R0
900$:
        RSB
        .PAGE
        .SBTTL  TERMIO - Control I/O to the terminal
TERMIO::
        .WORD   ^M<R2,R3,R4,R5,R6,R7>
        MOVC3   8(AP),@4(AP),TERMBUFF
        ADDL3   #1,8(AP),R6
        CMPL    (AP),#3
        BLEQ    100$
        BRW     200$
100$:
        CMPL    (AP),#2
        BGTR    120$
        TSTW    TERMON
        BEQL    160$
120$:
        TSTB    TERMOUT
        BEQL    130$
        MOVB    #CR,TERMBUFF-1[R6]
        INCL    R6
        $QIOW_S CHAN=TT,FUNC=#IO$_WRITEVBLK,P1=TERMLF,P2=R6
        BLBS    R0,150$
        BRW     ERREXT
130$:
        MOVW    8(AP),TERMDSC
        PUSHAQ  TERMDSC
        CALLS   #1,G^LIB$PUT_OUTPUT
        BLBS    R0,150$
        BRW     ERREXT
150$:
        TSTB    NOLOG
        BNEQ    170$
160$:
        MOVL    8(AP),R6
        BRW     600$
170$:
        BRW     900$
200$:
        MOVAL   TERMLF,R7
220$:
        TSTB    TERMIN
        BEQL    450$
        $QIOW_S CHAN=TT,FUNC=#IO$_READPROMPT,IOSB=TSTATUS,-
                P1=@12(AP),P2=16(AP),P5=R7,P6=R6
        BLBS    R0,300$
        BRW     ERREXT
300$:
        CMPW    TSTATUS+4,#CR
        BEQL    340$
        TSTB    HLPON
        BEQL    350$
        CVTWL   TSTATUS+2,R7
        CMPL    R7,16(AP)
        BGEQ    340$
        ADDL2   12(AP),R7
        MOVB    TSTATUS+4,(R7)
        INCW    TSTATUS+2
340$:
        BRW     500$
350$:
        CMPW    TSTATUS+4,#CZ
        BNEQ    400$
        BRW     EXIT
400$:
        MOVAL   TERMCR,R7
        ADDL3   #2,8(AP),R6
        BRW     220$
450$:
        MOVW    8(AP),TERMDSC
        PUSHAQ  TERMDSC
        CALLS   #1,G^LIB$PUT_OUTPUT
        BLBC    R0,460$
        MOVW    16(AP),DESC
        MOVL    12(AP),DESC+4
        PUSHAW  TSTATUS+2
        PUSHL   #0
        PUSHAQ  DESC
        CALLS   #3,G^LIB$GET_INPUT
        BLBS    R0,470$
        CMPL    R0,#RMS$_EOF
        BNEQ    460$
        BRW     EXIT
460$:
        BRW     ERREXT
470$:
        MOVW    #CR,TSTATUS+4
500$:
        TSTB    NOLOG
        BNEQ    900$
        MOVL    8(AP),R6
        TSTW    TSTATUS+2
        BLEQ    600$
        ADDL3   #TERMBUFF,R6,R7
        MOVC3   TSTATUS+2,@12(AP),(R7)
        ADDW2   TSTATUS+2,R6
600$:
        MOVW    R6,LOGRAB+RAB$W_RSZ
        $PUT    RAB=LOGRAB
        BLBS    R0,900$
        BRW     ERREXT
900$:
        RET
        .PAGE
        .SBTTL  Data definitions

        .PSECT  DATA,WRT,NOEXE,LONG

CR=^X0D
LF=^X0A
CZ=^X1A
ESC=^X1B

TERM:   .ASCID  /TT/
TT:     .BLKW   1

TSTATUS:: .BLKL 2

NLGMSG: .ASCIC  /        NOLOG/
LOGMSG: .ASCID  /        LOG=!AS/

SYSIN:  .ASCID  /SYS$INPUT/

SYSOUT: .ASCID  /SYS$OUTPUT/

SETLOW: .ASCII  <ESC>/[?3l/
SETHIGH: .ASCII <ESC>/[?3h/

MODBUF:
TT_CLASS: .BLKB 1
TT_TYPE: .BLKB  1
TT_WID: .BLKB   2
TT_CHAR: .BLKB  3
TT_LEN: .BLKB   1

TERMFLGS:
TERMIN: .BYTE   1
TERMOUT:: .BYTE 1

NEWWID:: .LONG  0
TERMWD:: .LONG  132

TERMCR: .BYTE   CR
TERMLF: .BYTE   LF
TERMBUFF:  .BLKB  200
TERMDSC: .WORD  0
        .WORD   ^X010E
        .ADDRESS TERMBUFF

GETCLS: .WORD   4
        .WORD   DVI$_DEVCLASS
        .ADDRESS IOCLASS
        .LONG   0
        .LONG   0
IOCLASS: .LONG  0

        .ALIGN  LONG

LOGFAB: $FAB    FAC=PUT,FOP=<MXV,SQO,TEF>,ORG=SEQ,RAT=CR,RFM=VAR,SHR=NIL,-
                NAM=LOGNBK
LOGNBK: $NAM    RSA=RESLOG,RSS=NAM$C_MAXRSS
LOGRAB: $RAB    FAB=LOGFAB,RBF=TERMBUFF,RAC=SEQ

RESLOG: .BLKB   NAM$C_MAXRSS

        .END
$*$*EOD*$*$
$ checksum TERMHDLR.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ exit

PORTIA@ENGVAX.SCG.HAC.COM (Portia 616-2635) (07/25/87)

$ show default
$ check_sum = 1521235
$ write sys$output "Creating AAAREADME.TXT"
$ create AAAREADME.TXT
$ DECK/DOLLARS="$*$*EOD*$*$"
     VFE is a block-oriented, type insensitive VMS file editor.  It
can edit user files, FOREIGN-mounted tapes, and disk devices.  Data
can be displayed in ASCII, EBCDIC, hex, binary, and integer format.
User-defined sections of single or multiple contiguous blocks can be
changed, compared, and transferred within a file or between files.
VFE also has a very fast search which can target a string, hex or
integer constant.  All or part of a terminal session can be logged
to a sequential file for later lineprinter output.

     For more information, see VFE.DOC.

     This is the second release of VFE, with many useful enhancements.
If you are a user of the original version, released on the fall 1984
VAX SIG tapes, be sure to look at VFENEW.DOC.

     This utility was presented at the "VAX magic" session of the fall
1984 DECUS symposium.  Submitted by:

     Ward Condit
     Maricopa Community Colleges
     P. O. Box 13349
     Phoenix, Az.  85002
$*$*EOD*$*$
$ checksum AAAREADME.TXT
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ check_sum = 1326833389
$ write sys$output "Creating COMMAND.MAR"
$ create COMMAND.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .TITLE  COMMAND Read and interpret command lines

        .ENABLE SUPPRESSION

        .LIBRARY        'VFELIB'

        $TPADEF

        .PSECT  CODE,EXE,NOWRT
        .PAGE
        .SBTTL  GETCMD - Get command
GETCMD::
100$:
        CLRB    HLPON
        MOVL    #25,OUTDSC
        TSTB    TAPFLG
        BNEQ    200$
        CMPL    BUFFCT,#1
        BNEQ    150$
        $FAO_S  CTRSTR=SOLDSK0,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=CURBLK
        BRW     300$
150$:
        $FAO_S  CTRSTR=SOLDSK1,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=CURBLK,P2=CURBCT
        BRB     300$
200$:
        TSTL    CURBCT
        BGTR    250$
        $FAO_S  CTRSTR=SOLTP0,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=CURFIL,P2=CURBLK
        BRB     300$
250$:
        $FAO_S  CTRSTR=SOLTP1,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=CURFIL,P2=CURBLK,P3=CURBCT
300$:
        INPUT   OUTDSC,OUT_BUFF,#80,FUNC
        CMPB    TSTATUS+2,#0
        BGTR    450$
        MOVL    #1,PARA1
        MOVAL   NEXT,JMPADR
        BRW     800$
450$:
        MOVZWL  TSTATUS+2,R3
        MOVAL   FUNC,R4
500$:
        CMPB    (R4),#^A/ /
        BNEQ    550$
        INCL    R4
        SOBGTR  R3,500$
        BRB     650$
550$:
        CMPB    (R4),#^A/a/
        BLSSU   600$
        CMPB    (R4),#^A/z/
        BGTRU   650$
        SUBB2   #^X20,(R4)
600$:
        CMPB    (R4),#^A/A/
        BLSS    650$
        CMPB    (R4),#^A/Z/
        BGTR    650$
        INCL    R4
        SOBGTR  R3,550$
650$:
        CLRL    JMPADR
        CLRL    MFLAG
        CLRL    SETMASK
        CLRL    SHOMASK
        CLRB    DPBFLG
        CLRB    RFLAG
        CLRB    LGFLAG
        CLRB    POSFLG
        MOVL    #TPA$K_COUNT0,TPBLK+TPA$L_COUNT
        MOVL    #TPA$M_ABBRFM,TPBLK+TPA$L_OPTIONS
        MOVZWL  TSTATUS+2,TPBLK+TPA$L_STRINGCNT
        MOVAL   FUNC,TPBLK+TPA$L_STRINGPTR
        PUSHAL  VFE_KEY
        PUSHAL  VFE_STATE
        PUSHAL  TPBLK
        CALLS   #3,G^LIB$TPARSE
        BLBS    R0,700$
        BSBW    ERROUT
        BRW     100$
700$:
        CMPL    #0,JMPADR
        BNEQ    800$
        BRW     100$
800$:
        RSB
        .PAGE
        .SBTTL  FPARSE - Parse file spec w/qualifiers
FPARSE::
        MOVL    #TPA$K_COUNT0,TPBLK+TPA$L_COUNT
        MOVL    #TPA$M_BLANKS!TPA$M_ABBRFM,TPBLK+TPA$L_OPTIONS
        MOVZWL  DESC,TPBLK+TPA$L_STRINGCNT
        MOVL    DESC+4,TPBLK+TPA$L_STRINGPTR
        CLRW    FDESC
        CLRL    SETMASK
        PUSHAL  VFE_KEY
        PUSHAL  FP1
        PUSHAL  TPBLK
        CALLS   #3,G^LIB$TPARSE
        BLBS    R0,200$
        BSBW    ERROUT
        BRB     600$
200$:
        TSTB    OVRFLG
        BEQL    800$
        TSTB    WRTFLG
        BEQL    800$
        OUTMSG  #NWOL,NWOMSG
        CLRW    OVRWRT
600$:
        CLRL    R0
800$:
        RSB
        .PAGE
        .SBTTL  Parser state table

COMMA=^A/,/
DQUOTE=^A/"/
SQUOTE=^A/'/
QUEST=^A/?/

        $INIT_STATE  VFE_STATE,VFE_KEY

        $STATE  BEGIN
        $TRAN   TPA$_DECIMAL,DEFGET,,,PARA1
        $TRAN   'ALPHA',PARAM2P,ALPHINIT
        $TRAN   'ASCII',PARAM2P,AINIT,ASCII,JMPADR
        $TRAN   'ADD',ADDPAR,ADDINI,ADD,JMPADR
        $TRAN   'BINARY',PARAM2P,AINIT,BINARY,JMPADR
        $TRAN   'CHANGE',CPARA,,CHANGE,JMPADR
        $TRAN   'CUT',PARAM2,CINIT,CUT,JMPADR
        $TRAN   'DIFFERENCES',PARAM2,DPINIT,DIFF,JMPADR
        $TRAN   'DATE',PARAM2P,DTINIT,DATE,JMPADR
        $TRAN   'EXIT',TSTEOS,,EXIT,JMPADR
        $TRAN   'EBCDIC',PARAM2P,AINIT,EBCDIC,JMPADR
        $TRAN   'EOF',TSTEOS,,EOF,JMPADR
        $TRAN   'FILE',FPARM
        $TRAN   'GET',PARAM1,GINIT,READ,JMPADR
        $TRAN   'HEX',PARAM2P,AINIT,HEX,JMPADR
        $TRAN   'HELP',HLPPAR,,HELP,JMPADR
        $TRAN   'IBYTE',PARAM2P,AINIT,IBYTE,JMPADR
        $TRAN   'IWORD',PARAM2P,IWINIT,IWLDSP,JMPADR
        $TRAN   'ILONG',PARAM2P,ILINIT,IWLDSP,JMPADR
        $TRAN   'LOCATE',LPARA,,LOCATE,JMPADR
        $TRAN   'LGLOBAL',LPARA,LGINIT,LOCATE,JMPADR
        $TRAN   'LAST',TSTEOS,,LAST,JMPADR
        $TRAN   'MULTI',PARAM2P,AINIT,MULTI,JMPADR
        $TRAN   'MOVE',NPARA,NINIT,MOVE,JMPADR
        $TRAN   'NEXT',NPARA,NINIT,NEXT,JMPADR
        $TRAN   'PASTE',PARAM2,DPINIT,PASTE,JMPADR
        $TRAN   'RECORD',PARAM2,RINIT,RECORD,JMPADR
        $TRAN   'REWIND',TSTEOS,,REWIND,JMPADR
        $TRAN   'SET',SETPAR,UCASE,SETCMD,JMPADR
        $TRAN   'SHOW',SHOPAR,UCASE,SHOCMD,JMPADR
        $TRAN   'TOP',TSTEOS,,TOP,JMPADR
        $TRAN   'WRITE',TSTEOS,,WRITEDISK,JMPADR
        $TRAN   '+',NPARA2,NINIT,NEXT,JMPADR
        $TRAN   '-',NPARA2,NINITM,NEXT,JMPADR
        $TRAN   TPA$_EOS,TPA$_EXIT,NINIT,NEXT,JMPADR
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,BDCOMM

        $STATE  DEFGET
        $TRAN   TPA$_EOS,TPA$_EXIT,,READ,JMPADR

        $STATE  PARAM2P
        $TRAN   '/',,UCASE
        $TRAN   TPA$_LAMBDA,PARAM2
        $STATE
        $TRAN   'PASTE',,PASTON
        $STATE  PARAM2
        $TRAN   TPA$_DECIMAL,,HEXTST,,PARA1
        $TRAN   TPA$_HEX,,,,PARA1
        $TRAN   COMMA,P2S2
        $TRAN   ':',P2S3,RECCHK
        $TRAN   TPA$_EOS,TPA$_EXIT
        $STATE
        $TRAN   COMMA,P2S2
        $TRAN   ':',P2S3,RECCHK
        $TRAN   TPA$_EOS,TPA$_EXIT,SINGLE
        $STATE  P2S2
        $TRAN   TPA$_DECIMAL,TSTEOS,,,PARA2
        $STATE  P2S3
        $TRAN   TPA$_DECIMAL,,HEXTST,,PARA2
        $TRAN   TPA$_HEX,,,,PARA2
        $STATE
        $TRAN   TPA$_EOS,TPA$_EXIT,OFFSET

        $STATE  PARAM1
        $TRAN   TPA$_DECIMAL,TSTEOS,,,PARA1
        $TRAN   TPA$_EOS,TPA$_EXIT

        $STATE  NPARA
        $TRAN   '-',,NINITM
        $TRAN   '+'
        $TRAN   TPA$_LAMBDA
        $STATE  NPARA2
        $TRAN   TPA$_DECIMAL,,,,PARA1
        $TRAN   TPA$_LAMBDA
        $STATE
        $TRAN   TPA$_EOS,TPA$_EXIT,NEGATE

        $STATE  ADDPAR
        $TRAN   '-',,,1,MFLAG
        $TRAN   '+'
        $TRAN   TPA$_LAMBDA
        $STATE
        $TRAN   'H',HEXX
        $TRAN   'h',HEXX
        $TRAN   '0',OCT
        $TRAN   TPA$_DECIMAL,ADDP2,ACCUML
        $STATE  HEXX
        $TRAN   TPA$_HEX,ADDP2,ACCUML
        $STATE  OCT
        $TRAN   TPA$_OCTAL,ADDP2,ACCUML
        $STATE  ADDP2
        $TRAN   COMMA,ADDPAR
        $TRAN   TPA$_EOS,TPA$_EXIT

        $STATE  CPARA
        $TRAN   TPA$_DECIMAL,,HEXTST,,PARA1
        $TRAN   TPA$_HEX,,,,PARA1
        $TRAN   '*',,CHGLOC
        $TRAN   TPA$_EOS,,CHGLOC
        $STATE
        $TRAN   TPA$_EOS,TPA$_EXIT,CNULL
        $TRAN   COMMA,QPARSE

        $STATE  LPARA
        $TRAN   TPA$_EOS,TPA$_EXIT,LNULL
        $TRAN   TPA$_LAMBDA,QPARSE

        $STATE  QPARSE
        $TRAN   TPA$_HEX,TSTEOS,CNUM
        $TRAN   '+',DECCL
        $TRAN   '-',DECCL,,1,MFLAG
        $TRAN   SQUOTE,,SPACON,,QCHAR
        $TRAN   DQUOTE,,SPACON,,QCHAR
        $STATE
        $TRAN   !QSTRING,,,,QDESC
        $STATE
        $TRAN   TPA$_EOS,TPA$_EXIT,CHKSTR
        $TRAN   TPA$_ANY,TSTEOS,CHKSTR

        $STATE  QSTRING
        $TRAN   TPA$_ANY,QSTRING,TESTQ
        $TRAN   TPA$_LAMBDA,TPA$_EXIT

        $STATE  DECCL
        $TRAN   TPA$_DECIMAL,TSTEOS,CDEC

        $STATE  FPARM
        $TRAN   QUEST,TSTEOS,,SHOFILE,JMPADR
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,GENDESC,GETFILE,JMPADR

        $STATE  HLPPAR
        $TRAN   TPA$_BLANK
        $TRAN   TPA$_LAMBDA
        $STATE
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,GENDESC

        $STATE  SETPAR
        $TRAN   !SETSUB,TSTEOS
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,BDCOMM

        $STATE  SHOPAR
        $TRAN   'MODES',TSTEOS,,<^X1>,SHOMASK
        $TRAN   'CHANGE',TSTEOS,,<^X2>,SHOMASK
        $TRAN   'LOCATE',TSTEOS,,<^X4>,SHOMASK
        $TRAN   'PASTE',TSTEOS,,<^X8>,SHOMASK
        $TRAN   'FILE',TSTEOS,,<^X10>,SHOMASK
        $TRAN   'DEVICE',TSTEOS,,<^X10>,SHOMASK
        $TRAN   'ALL',TSTEOS,,<^X1F>,SHOMASK
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,BDCOMM

        $STATE  FP1
        $TRAN   TPA$_BLANK,,UCASE
        $TRAN   TPA$_LAMBDA,,UCASE

        $STATE  FP2
        $TRAN   '/',FP3
        $TRAN   TPA$_EOS,TPA$_EXIT
        $TRAN   TPA$_LAMBDA,FP4

        $STATE  FP3
        $TRAN   'OVERRIDE',FP1,SETOVR
        $TRAN   'WRITE',FP1,SETWRT
        $TRAN   'NOREWIND',FP3A,CHAR3
        $TRAN   'REWIND',FP1
        $TRAN   'POSITION',FP3B
        $TRAN   TPA$_LAMBDA,,TSTINIT
        $STATE
        $TRAN   !SETSUB,FP1
        $STATE  FP3A
        $TRAN   TPA$_LAMBDA,FP1,CLRREW
        $STATE  FP3B
        $TRAN   !POSSUB,FP1

        $STATE  FP4
        $TRAN   TPA$_LAMBDA,,TESTF
        $STATE
        $TRAN   !FSTRING,,,,FDESC

        $STATE  FP5
        $TRAN   TPA$_BLANK,FP2
        $TRAN   TPA$_LAMBDA,FP2

        $STATE  SETSUB
        $TRAN   'LOG',LOGPAR,,<^X1>,SETMASK
        $TRAN   'NOLOG',TPA$_EXIT,CHAR3,<^X1000>,SETMASK
        $TRAN   'DISPLAY',TPA$_EXIT,,<^X2>,SETMASK
        $TRAN   'NODISPLAY',TPA$_EXIT,CHAR3,<^X2000>,SETMASK
        $TRAN   'SIGN',TPA$_EXIT,,<^X4>,SETMASK
        $TRAN   'NOSIGN',TPA$_EXIT,CHAR3,<^X4000>,SETMASK
        $TRAN   'HEADER',TPA$_EXIT,,<^X8>,SETMASK
        $TRAN   'NOHEADER',TPA$_EXIT,CHAR3,<^X8000>,SETMASK
        $TRAN   'CASE',TPA$_EXIT,,<^X10>,SETMASK
        $TRAN   'NOCASE',TPA$_EXIT,CHAR3,<^X10000>,SETMASK
        $TRAN   'RADIX',RADPAR
        $TRAN   'BUFF',BUFPAR
        $TRAN   'SKIP',SKIPPAR
        $TRAN   'WIDTH',WIDPAR
        $TRAN   'CHARSET',CHARPAR
        $TRAN   'POSITION',POSPAR

        $STATE  LOGPAR
        $TRAN   '='
        $TRAN   TPA$_LAMBDA,TPA$_EXIT,LOGDEF
        $STATE
        $TRAN   !FSTRING,TPA$_EXIT,,,DESC

        $STATE  RADPAR
        $TRAN   '='
        $STATE
        $TRAN   'HEX',TPA$_EXIT,,<^X20>,SETMASK
        $TRAN   'DECIMAL',TPA$_EXIT,,<^X20000>,SETMASK

        $STATE  BUFPAR
        $TRAN   '=',,,<^X100000>,SETMASK
        $STATE
        $TRAN   TPA$_DECIMAL,TPA$_EXIT,,,NBUFCT

        $STATE  SKIPPAR
        $TRAN   '='
        $STATE
        $TRAN   'FAST',TPA$_EXIT,,<^X100>,SETMASK
        $TRAN   'SLOW',TPA$_EXIT,,<^X200>,SETMASK
        $TRAN   'NORMAL',TPA$_EXIT,,<^X400>,SETMASK

        $STATE  WIDPAR
        $TRAN   '=',,,<^X800>,SETMASK
        $STATE
        $TRAN   TPA$_DECIMAL,TPA$_EXIT,,,NEWWID

        $STATE  CHARPAR
        $TRAN   '='
        $STATE
        $TRAN   'EBCDIC',TPA$_EXIT,,<^X40>,SETMASK
        $TRAN   'ASCII',TPA$_EXIT,,<^X40000>,SETMASK

        $STATE  POSPAR
        $TRAN   !POSSUB,TPA$_EXIT

        $STATE  POSSUB
        $TRAN   '=',,POSINIT
        $STATE
        $TRAN   '('
        $TRAN   TPA$_DECIMAL,TPA$_EXIT,,,POSBLK
        $STATE
        $TRAN   TPA$_DECIMAL,,,,POSFIL
        $STATE
        $TRAN   ':'
        $STATE
        $TRAN   TPA$_DECIMAL,,,,POSBLK
        $STATE
        $TRAN   ')',TPA$_EXIT

        $STATE  FSTRING
        $TRAN   TPA$_ANY,,FSSL

        $STATE  FS1
        $TRAN   TPA$_BLANK,TPA$_EXIT
        $TRAN   TPA$_ANY,FS1,FSSL
        $TRAN   TPA$_LAMBDA,TPA$_EXIT

        $STATE  TSTEOS
        $TRAN   TPA$_EOS,TPA$_EXIT

        $END_STATE
        .PAGE
        .SBTTL  Action routines

ALPHINIT:
        .WORD   0
        MOVAL   ASCII,JMPADR
        TSTB    EBCFLG
        BEQL    100$
        MOVAL   EBCDIC,JMPADR
100$:
        MOVL    #1,DSPCNT
        CLRL    PARA1
        MNEGL   #1,PARA2
        RET

AINIT:
        .WORD   0
        MOVL    #1,DSPCNT
        CLRL    PARA1
        MNEGL   #1,PARA2
        RET

CINIT:
        .WORD   0
        MOVL    #1,DSPCNT
        CLRL    PARA1
        MOVL    CURBCT,PARA2
        INCL    MFLAG
        RET

DPINIT:
        .WORD   0
        MOVL    #1,DSPCNT
        MOVL    PBOFF,PARA1
        SUBL3   PBOFF,CURBCT,PARA2
        CMPL    PARA2,PBBCT
        BLEQ    100$
        MOVL    PBBCT,PARA2
100$:
        DECL    MFLAG
        RET

DTINIT:
        .WORD   0
        MOVL    #8,DSPCNT
        MNEGL   #1,PARA1
        RET

IWINIT:
        .WORD   0
        MOVL    #2,DSPCNT
        CLRL    PARA1
        MNEGL   #1,PARA2
        MOVL    #8,WLPARM
        MOVL    #6,WLPOSN
        RET

ILINIT:
        .WORD   0
        MOVL    #4,DSPCNT
        CLRL    PARA1
        MNEGL   #1,PARA2
        MOVL    #4,WLPARM
        MOVL    #11,WLPOSN
        RET

LGINIT:
        .WORD   0
        MOVB    #1,LGFLAG
        RET

RINIT:
        .WORD   0
        MNEGL   #1,PARA1
        MNEGL   #1,PARA2
        MOVB    #1,RFLAG
        RET

PASTON:
        .WORD   0
        INCB    DPBFLG
        DIVL3   DSPCNT,PBBCT,PARA2
        RET

HEXTST:
        .WORD   0
        TSTB    HEXFLG
        BEQL    100$
        CLRL    R0
100$:
        RET

RECCHK:
        .WORD   0
        TSTB    RFLAG
        BEQL    100$
        CLRL    R0
100$:
        RET

SINGLE:
        .WORD   0
        TSTL    MFLAG
        BNEQ    100$
        MOVL    #1,PARA2
        BRB     200$
100$:
        SUBL3   PARA1,CURBCT,PARA2
        TSTL    MFLAG
        BGTR    200$
        CMPL    PARA2,PBBCT
        BLEQ    200$
        MOVL    PBBCT,PARA2
200$:
        RET

OFFSET:
        .WORD   0
        SUBL2   PARA1,PARA2
        ADDL2   DSPCNT,PARA2
        BGTR    100$
        CLRL    PARA2
100$:
        DIVL2   DSPCNT,PARA2
        RET

ADDINI:
        .WORD   0
        CLRL    ACCUM
        CLRL    MFLAG
        RET

ACCUML:
        .WORD   0
        CMPL    MFLAG,#0
        BEQL    100$
        SUBL2   TPA$L_NUMBER(AP),ACCUM
        BRB     200$
100$:
        ADDL2   TPA$L_NUMBER(AP),ACCUM
200$:
        CLRL    MFLAG
        RET

GINIT:
        .WORD   0
        MOVL    CURBLK,PARA1
        RET

NINIT:
        .WORD   0
        CLRL    MFLAG
        MOVL    #1,PARA1
        RET

NINITM:
        .WORD   0
        MOVL    #1,MFLAG
        MOVL    #1,PARA1
        RET

NEGATE:
        .WORD   0
        TSTL    MFLAG
        BEQL    100$
        MNEGL   PARA1,PARA1
100$:
        RET

CHGLOC:
        .WORD   0
        MOVL    LPTR,PARA1
        DECL    PARA1
        RET

CNULL:
        .WORD   0
        TSTW    CSTRL
        BGTR    100$
        CLRL    R0
        BRB     200$
100$:
        MOVW    CSTRL,QDESC
        MOVAL   CSTR,QDESC+4
        MOVB    CSTRT,QTYPE
200$:
        RET

LNULL:
        .WORD   0
        CMPW    LSTRL,#0
        BGTR    100$
        CLRL    R0
        BRB     200$
100$:
        MOVW    LSTRL,QDESC
        MOVAL   LSTR,QDESC+4
        MOVB    LSTRT,QTYPE
200$:
        RET

CNUM:
        .WORD   ^M<R2,R3,R4,R5,R6,R7,R8>
        MOVAL   QSTR,R6
        MOVL    R6,QDESC+4
        ADDL3   #1,TPA$L_TOKENCNT(AP),R7
        DIVL2   #2,R7
        MOVW    R7,QDESC
        CMPL    R7,#4
        BLEQ    100$
        SUBL3   #4,R7,R8
        MOVC5   #0,BUFF,#0,R8,(R6)
        ADDL2   R8,R6
        MOVL    #4,R7
100$:
        MOVAL   TPA$L_NUMBER(AP),R8
        ADDL2   R7,R8
200$:
        MOVB    -(R8),(R6)+
        SOBGTR  R7,200$
        MOVB    #3,QTYPE
        MOVL    #1,R0
        RET

CDEC:
        .WORD   0
        MOVL    TPA$L_NUMBER(AP),R1
        CMPL    TPA$L_TOKENCNT(AP),#5
        BGTR    600$
        CMPL    TPA$L_TOKENCNT(AP),#3
        BGTR    400$
        CMPL    R1,#255
        BGTR    400$
        TSTL    MFLAG
        BEQL    300$
        CMPL    R1,#128
        BGTR    400$
        MNEGL   R1,R1
300$:
        MOVB    R1,QSTR
        MOVW    #1,QDESC
        BRB     850$
400$:
        CMPL    R1,#65535
        BGTR    600$
        TSTL    MFLAG
        BEQL    500$
        CMPL    R1,#32768
        BGTR    600$
        MNEGL   R1,R1
500$:
        MOVW    R1,QSTR
        MOVW    #2,QDESC
        BRB     850$
600$:
        TSTL    MFLAG
        BEQL    800$
        TSTL    R1
        BGEQ    700$
        CLRL    R0
        BRB     900$
700$:
        MNEGL   R1,R1
800$:
        MOVL    R1,QSTR
        MOVW    #4,QDESC
850$:
        MOVAL   QSTR,QDESC+4
        MOVB    #1,QTYPE
        TSTL    MFLAG
        BEQL    900$
        MOVB    #2,QTYPE
900$:
        RET

SPACON:
        .WORD   0
        MOVL    #TPA$M_ABBRFM!TPA$M_BLANKS,TPA$L_OPTIONS(AP)
        RET

CHKSTR:
        .WORD   0
        CLRB    QTYPE
        MOVL    #TPA$M_ABBRFM,TPA$L_OPTIONS(AP)
        CMPW    QDESC,#0
        BGTR    100$
        CLRL    R0
100$:
        RET

TESTQ:
        .WORD   0
        CMPB    TPA$B_CHAR(AP),QCHAR
        BNEQ    100$
        CLRL    R0
100$:
        RET

UCASE:
        .WORD   ^M<R2,R3>
        MOVL    TPA$L_STRINGCNT(AP),R2
        BLEQ    900$
        MOVL    TPA$L_STRINGPTR(AP),R3
100$:
        CMPB    (R3),#^A/a/
        BLSS    200$
        CMPB    (R3),#^A/z/
        BGTR    200$
        SUBB2   #^X20,(R3)
200$:
        INCL    R3
        SOBGTR  R2,100$
900$:
        RET

CHAR3:
        .WORD   0
        CMPL    TPA$L_TOKENCNT(AP),#3
        BGEQ    100$
        CLRL    R0
100$:
        RET

GENDESC:
        .WORD   0
        MOVW    TPA$L_STRINGCNT(AP),DESC
        MOVL    TPA$L_STRINGPTR(AP),DESC+4
        RET

LOGDEF:
        .WORD   0
        MOVQ    DEFLOG,DESC
        RET

BDCOMM:
        .WORD   0
        OUTMSG  #BDCL,BDC
        CLRL    JMPADR
        RET

SETOVR:
        .WORD   0
        MOVB    #1,OVRFLG
        RET

SETWRT:
        .WORD   0
        MOVB    #1,WRTFLG
        RET

CLRREW:
        .WORD   0
        MOVB    #1,NOREW
        RET

TSTINIT:
        .WORD   0
        TSTB    INITFLG
        BNEQ    100$
        CLRL    R0
100$:
        RET

TESTF:
        .WORD   0
        TSTW    FDESC
        BEQL    100$
        CLRL    R0
100$:
        RET

POSINIT:
        .WORD   0
        MOVB    #1,POSFLG
        MOVL    CURFIL,POSFIL
        RET

FSSL:
        .WORD   0
        CMPB    TPA$B_CHAR(AP),#^A./.
        BNEQ    100$
        CLRL    R0
100$:
        RET
        .PAGE
        .SBTTL  Data definitions

        .PSECT  DATA,WRT,NOEXE

SOLDSK0: .ASCID /!UL> /
SOLDSK1: .ASCID /!UL(!UL)> /
SOLTP0: .ASCID  /!SL:!SL> /
SOLTP1: .ASCID  /!SL:!SL(!UL)> /
FUNC:   .BLKB   80

DEFLOG: .ASCID  /VFE.LOG/

BDC:    .ASCII  /Invalid command./
BDCL=.-BDC

NWOMSG: .ASCII  "/OVERRIDE and /WRITE may not be used together."
NWOL=.-NWOMSG

TPBLK:  .BLKB   TPA$K_LENGTH0

INITFLG:: .BYTE 1
JMPADR:: .LONG  0
SETMASK:: .LONG 0
SHOMASK:: .LONG 0
PARA1:: .LONG   0
        .LONG   0
PARA2:: .LONG   0

MFLAG:  .LONG   0
DPBFLG:: .BYTE  0
RFLAG:  .BYTE   0

QCHAR:  .BYTE   0
QDESC:: .QUAD   0
QTYPE:: .BYTE   0
QSTR:   .BLKB   100

        .END
$*$*EOD*$*$
$ checksum COMMAND.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ check_sum = 1327248427
$ write sys$output "Creating VFE.DOC"
$ create VFE.DOC
$ DECK/DOLLARS="$*$*EOD*$*$"
     The following files are contained in this release (V2.0) of VFE:

     VFE.DOC - This document
     VFENEW.DOC - A description of changes from V1.0 to V2.0
     VFE.EXE - The VFE utility in executable format (linked under VMS 4.2)
     VFE.HLB - The VFE help file in library format
     VFE.RNH - Source for the help file in runoff format

               Source and objects for the VFE utility:

     VFE, COMMAND, DISPLAY, FILEHDLR, TERMHDLR, VFELIB

-----------------------------------------------------------------------------

     To install VFE:

1) Copy the file VFE.HLB to SYS$HELP.  This is the default - you may decide  to
   keep  the  help  file in a different directory, in which case line # 1086 of
   VFE.MAR must be changed and a new executable produced.

2) Copy the file VFE.EXE to SYS$SYSTEM, or wherever else you choose to keep it.
   (Relink first if your system level is earlier than VMS 4.2 - see below)

3) Modify the LOGIN.COM file(s) of the users who are to use VFE by inserting:

   $ VFE:==$VFE                       (if VFE resides in SYS$SYSTEM)
   $ VFE:==$device:[directory]VFE     (otherwise)  <device> is mandatory!

------------------------------------------------------------------------------

To compile a single module, set your default to a directory which contains  the
VFE source (be sure VFELIB.MLB is present) and type:

   $ MACRO <name>

You will need to produce a new executable if you change a module or if your VMS
level is lower than 4.2.  To do this, type:

   $ LINK VFE+COMMAND+DISPLAY+FILEHDLR+TERMHLDR

No special options or parameters are required.

To produce a new HELP library file, type:

   $ RUNOFF VFE.RNH
   $ LIBRARY/CREATE/HELP VFE.HLB VFE.HLP

------------------------------------------------------------------------------

To execute VFE once it is installed and the symbol VFE is known, type:

   $ VFE <file>

The <file> parameter is required.   If  not  supplied,  a  file  name  will  be
solicited.  Commands cannot be given until a file is open for edit.

Commands are solicited with the current block number followed with  a  "greater
than"  sign  (>).   Commands  are  documented  in the help file.  A list of all
commands can be obtained by typing HELP.  Specific info on a particular command
is displayed by typing HELP <command>.  Most commands can be abbreviated to one
or two letters.  The  unessential  part  of  each  command  word  is  shown  in
parenthesis in the help file.

The signon  line  has  optional  parameters  which  are  not  shown  above.   A
description of the complete signon line is available via HELP SIGNON.

------------------------------------------------------------------------------

Read-only mode is the default access mode.  In  read-only  mode,  all  commands
except  for  WRITE  are  allowed.   Even  for experienced users, it is strongly
suggested that VFE be operated only in read-only  mode  when  examining  system
files.   Critical  files for which there exist no current backup should also be
examined in read-only mode.

------------------------------------------------------------------------------

When using VFE interactively, control-C interrupts are recognized  and  can  be
used  to  interrupt a large volume of output or a LOCATE or LGLOBAL search of a
large file.  In either case, the user will be left positioned at the last block
processed.   It  is  perfectly  valid,  for example, to type LOCATE "ABC", wait
awhile, control-C, and then another LOCATE to continue the search.   Since  the
block number is displayed at every prompt, this is particularly handy when only
a part of a very large file is to be searched.

------------------------------------------------------------------------------

Questions, comments, and suggestions for improvements will be gladly  accepted.
If  you  have  a suggested improvement, please include a description of how you
would like to see it implemented.  Address all correspondence to:

     Ward Condit
     Maricopa Community Colleges
     P.  O.  Box 13349
     Phoenix, Az.  85002
     (602) 267-4403
$*$*EOD*$*$
$ checksum VFE.DOC
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ check_sum = 319015572
$ write sys$output "Creating VFENEW.DOC"
$ create VFENEW.DOC
$ DECK/DOLLARS="$*$*EOD*$*$"
                            * VFE version 2.0 *

     VFE level 2.0 contains many significant enhancements to the earlier  level
(1.0).  The new version contains more than twice as many lines of code, and has
been broken into five modules for  compilation  efficiency.   It  is,  however,
almost totally upward-compatible with version 1.0.

     This level has been run exclusively on VMS 4+ systems.  I do  not  have  a
version  3  system  to test with, but do not know of any limitations that would
preclude operation on such a system, other than the required relink.

     Following are the major enhancements in VFE 2.0:

   - Operation has been extended to include tapes and disk devices.  Tapes must
     be  mounted  FOREIGN  and  are  read-only.   Disk  devices  require LOG_IO
     privilege to edit, and are also read-only unless FOREIGN mounted.

   - The original block restrictions on CUT and PASTE have been eliminated.   A
     new  command,  SET  BUFF,  is  available  for  disk operation which allows
     expansion of the current and paste buffers.  "Chunks" of data which can be
     up to 50 blocks in size and begin at an arbitrary location can be compared
     and moved within a file or between files.

   - The RECORD command will now search for the record start address  within  a
     positioned block if none is given.  This has proven to be extremely useful
     for examining very large print files at locations hundreds or thousands of
     blocks  from  the beginning.  There is also a new output format, activated
     by SET NOHEADER, which causes  only  the  record  data  to  be  displayed,
     producing output similar to TYPE.

   - The EBCDIC character set is now fully supported for display,  change,  and
     locate operations.  SET CHARSET can be used to select the character set to
     be used (ASCII is the default).

   - The LOCATE command now can search in case-insensitive mode with  character
     string  data,  as  directed  by  the  SET  NOCASE command.  There is a new
     command, LGLOBAL, which can search for all occurrences of a target  string
     within a file or device.

   - There are two new display  formats,  MULTI  and  BINARY.   MULTI  displays
     simultaneously in character and hex format.

   - Most display commands  now  output  and  accept  hex  byte  addresses,  as
     directed  by  SET  RADIX.   Ranges  can  now be given in either counted or
     address-delimited forms (see HELP RANGE).

   - VFE now is aware of SYS$INPUT and SYS$OUTPUT, so can be  run  from  within
     command files and from batch jobs.

   - Most display commands now have a normal and a wide output size.  The  wide
     format can be used to save paper and display more information on a screen.
     There is now a SET WIDTH command  which  can  change  the  terminal  width
     dynamically.

   - A SHOW command has been added to  display  useful  information  about  the
     current VFE environment.

   - The VFE command line can now be used to specify default  SET  options  and
     file qualifiers.  See HELP SIGNON.

     These and other minor enhancements have been designed as much as  possible
to  be upward-compatible with VFE 1.0.  The following are changes which are not
compatible with the earlier version.

   - The ROTATE command has been removed, since the current and  paste  buffers
     can  now be of different lengths.  Contents of the paste buffer can now be
     examined by adding the /PASTE option to most display commands.

   - The range specification on DIFFERENCES originally applied to both buffers.
     Since  the  paste  buffer can now be cut with any desired byte offset, all
     operations with  it  begin  at  its  own  byte  zero,  and  the  range  on
     DIFFERENCES  only  applies  to the current buffer.  The following examples
     illustrate this change:

  V1.0: CUT  DIFF          V2.0: CUT          DIFF (no change)
  V1.0: CUT  DIFF 300,100  V2.0: CUT 300,100  DIFF 300,100
  V1.0: CUT  DIFF 300,100  V2.0: CUT 300,100  DIFF (range defaults to CUT rng)
  V1.0: CUT  DIFF 300      V2.0: CUT 300,1    DIFF (count doesn't default to 1)

   - The method of specifiying WRITE access to a file has changed.  The  /WRITE
     qualifier  is  used  now  instead of the "pound" sign (#).  Information on
     specification of /WRITE is now in the help file.  It  was  felt  that  few
     users would wish to restrict this type of access.  Anyone wishing to do so
     with the new version may remove line 290 of COMMAND and edit the help file
     source to their liking.

   - The command used to display the current file has been changed from "F?" to
     SHOW FILE.  The original method, though undocumented, still operates.
$*$*EOD*$*$
$ checksum VFENEW.DOC
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ exit

PORTIA@ENGVAX.SCG.HAC.COM (Portia 616-2635) (07/25/87)

$ show default
$ check_sum = 1030314170
$ write sys$output "Creating DISPLAY.MAR"
$ create DISPLAY.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .TITLE  DISPLAY VFE formatted-output routines

        .ENABLE SUPPRESSION

        .LIBRARY        'VFELIB'

        .PSECT  CODE,EXE,NOWRT
        .PAGE
        .SBTTL  ASCII - Display in ASCII format
ASCII::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    #8,R1
        BSBW    ALIGN
        MOVB    #^A/ /,R9
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC6496,PARA2
        MOVL    LC0812,R8
        MOVB    #^A/ /,(R6)+
        BRB     350$
300$:
        MOVB    #^A/|/,(R6)+
350$:
        MOVL    #8,R7
400$:
        SOBGEQ  R10,600$
        MOVB    (R4)+,R9
        CMPB    R9,#32
        BLSS    500$
        CMPB    R9,#127
        BNEQ    600$
500$:
        MOVB    #^A/./,R9
600$:
        MOVB    R9,(R6)+
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,400$
        SOBGTR  R8,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  EBCDIC - Display in EBCDIC format
EBCDIC::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    #8,R1
        BSBW    ALIGN
        MOVL    #^X40,R9
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC6496,PARA2
        MOVL    LC0812,R8
        MOVB    #^A/ /,(R6)+
        BRB     350$
300$:
        MOVB    #^A/|/,(R6)+
350$:
        MOVL    #8,R7
400$:
        SOBGEQ  R10,600$
        MOVZBL  (R4)+,R9
600$:
        MOVB    EBCTBL[R9],(R6)+
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,400$
        SOBGTR  R8,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  IBYTE - Display in integer byte format
IBYTE::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    PARA1,PARA2
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC1624,PARA2
        MOVL    LC1624,R7
        MOVB    #^A/ /,(R6)+
300$:
        CLRQ    R9
        MOVB    #^A/ /,R11
        CVTBL   (R4)+,R8
        BGEQ    400$
        TSTB    SGNFLG
        BNEQ    360$
        MOVZBL  R8,R8
        BRW     400$
360$:
        MOVB    #^A/-/,R11
        MNEGL   R8,R8
400$:
        INCL    R10
        EDIV    #10,R8,R8,-(SP)
        BNEQ    400$
        SUBL3   R10,#3,R9
        BLEQ    550$
500$:
        MOVB    #^A/ /,(R6)+
        SOBGTR  R9,500$
550$:
        MOVB    R11,(R6)+
600$:
        ADDL3   #^A/0/,(SP)+,R3
        MOVB    R3,(R6)+
        SOBGTR  R10,600$
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  IWLDSP - Display in int word/lword fmt
IWLDSP::
        BSBW    SETUP
        BLBS    R0,50$
        BRW     980$
50$:
        MOVL    #SS$_NORMAL,SVSTAT
100$:
        MOVL    PARA1,PARA2
        CLRL    R6
        EDIV    DSPCNT,R5,R5,R6
        MOVL    R6,OVERFL
        BEQL    120$
        INCL    R5
        SUBL3   R6,DSPCNT,OVERFL
120$:
        TSTL    REM
        BLEQ    200$
        CLRL    NXTBCT
        MOVL    SVSTAT,R0
        BLBC    R0,140$
        DIVL3   #512,CURBCT,R1
        ADDL2   CURBLK,R1
        MULL3   #512,BUFFCT,R2
        BSBW    READINT
        MOVL    R0,SVSTAT
        BLBS    R0,200$
140$:
        TSTL    OVERFL
        BLEQ    200$
        SOBGTR  R5,200$
        BRW     920$
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   WLINC,PARA2             ; 16 or 32 dep on width
        MOVL    WLCNT,R7                ; WLPARM*2 if wide display
300$:
        CLRQ    R9
        MOVB    #^A/ /,R11
        CMPL    WLPARM,#4
        BEQL    340$
        CVTWL   (R4)+,R8
        BGEQ    400$
        TSTB    SGNFLG
        BNEQ    360$
        MOVZWL  R8,R8
        BRB     400$
340$:
        MOVL    (R4)+,R8
        BGEQ    400$
        TSTB    SGNFLG
        BEQL    400$
360$:
        MOVB    #^A/-/,R11
        MNEGL   R8,R8
400$:
        INCL    R10
        EDIV    #10,R8,R8,-(SP)
        BNEQ    400$
        SUBL3   R10,WLPOSN,R9
500$:
        MOVB    #^A/ /,(R6)+
        SOBGTR  R9,500$
        MOVB    R11,(R6)+
600$:
        ADDL3   #^A/0/,(SP)+,R3
        MOVB    R3,(R6)+
        SOBGTR  R10,600$
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        TSTB    STOP
        BEQL    810$
        BRW     900$
810$:
        ADDL2   #1,R5
        SOBGTR  R5,820$
        BRB     830$
820$:
        BRW     200$
830$:
        MOVL    SVSTAT,R0
        BLBS    R0,840$
        TSTB    TAPFLG
        BNEQ    835$
        CMPL    NXTBCT,#512
        BGEQ    840$
835$:
        BRW     920$
840$:
        CMPL    REM,OVERFL
        BGTR    845$
        BRW     900$
845$:
        MOVL    CURBCT,R6
        MOVC3   NXTBCT,BUFF(R6),BUFF
        MOVL    NXTBCT,CURBCT
        MOVL    #1,R1
        TSTB    TAPFLG
        BNEQ    850$
        DIVL3   #512,R6,R1
850$:
        ADDL2   R1,CURBLK
        BSBW    BLOCK
        CLRL    LPTR
        MNEGL   #1,RECPTR
        MOVL    #1,R0
        MOVL    OVERFL,PARA1
        MOVAL   BUFF,R4
        ADDL2   PARA1,R4
        CMPL    REM,CURBCT
        BGTR    860$
        SUBL3   PARA1,REM,R5
        CLRL    REM
        BRB     880$
860$:
        SUBL2   CURBCT,REM
        SUBL3   PARA1,CURBCT,R5
880$:
        BRW     100$
900$:
        TSTL    REM
        BLEQ    980$
        BRB     950$
920$:
        TSTB    TAPFLG
        BEQL    930$
        CMPL    R0,#SS$_ENDOFFILE
        BEQL    940$
930$:
        BSBW    ERROUT
        BRB     950$
940$:
        OUTMSGC EOF
950$:
        BSBW    BACKSPACE
980$:
        RSB
        .PAGE
        .SBTTL  HEX - Display in hexadecimal format
HEX::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    #4,R1
        BSBW    ALIGN
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC3248,PARA2
        MOVL    LC0812,R8
300$:
        MOVL    #4,R7
        MOVB    #^A/ /,(R6)+
400$:
        SOBGEQ  R10,500$
        EXTZV   #4,#4,(R4),R9
        MOVB    HEXD[R9],(R6)+
        EXTZV   #0,#4,(R4)+,R9
        MOVB    HEXD[R9],(R6)+
        BRB     600$
500$:
        MOVW    #^A/  /,(R6)+
600$:
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,400$
        SOBGTR  R8,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  BINARY - Display in binary format
BINARY::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    PARA1,PARA2
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC0812,PARA2
        MOVL    LC0812,R8
300$:
        MOVL    #7,R7
        MOVB    (R4)+,R10
        MOVB    #^A/ /,(R6)+
400$:
        EXTZV   R7,#1,R10,R9
        ADDB3   #^A/0/,R9,(R6)+
        SOBGEQ  R7,400$
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R8,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  MULTI - Display combination alpha/hex
MULTI::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        MOVL    #4,R1
        BSBW    ALIGN
200$:
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC3248,PARA2
        MOVQ    R4,R4R5S
        MOVL    R10,R9R10S
        MOVL    #1,R11
        BRB     280$
250$:
        MOVC3   #5,SP5,OUT_BUFF
        MOVAL   OUT_BUFF+5,R6
        MOVQ    R4R5S,R4
        MOVL    R9R10S,R10
280$:
        MOVL    LC0812,R8
300$:
        MOVL    #4,R7
        MOVB    #^A/ /,(R6)+
400$:
        SOBGEQ  R10,500$
        BLBC    R11,450$
        MOVB    #^A/ /,(R6)+
        MOVB    (R4)+,R9
        TSTB    EBCFLG
        BNEQ    440$
        CMPB    R9,#32
        BLSS    420$
        CMPB    R9,#127
        BNEQ    430$
420$:
        MOVB    #^A/./,R9
430$:
        MOVB    R9,(R6)+
        BRB     600$
440$:
        MOVB    EBCTBL[R9],(R6)+
        BRB     600$
450$:
        EXTZV   #4,#4,(R4),R9
        MOVB    HEXD[R9],(R6)+
        EXTZV   #0,#4,(R4)+,R9
        MOVB    HEXD[R9],(R6)+
        BRB     600$
500$:
        MOVW    #^A/  /,(R6)+
600$:
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,400$
        SOBGTR  R8,300$
800$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        SOBGEQ  R11,830$
        BRB     850$
830$:
        BRW     250$
850$:
        TSTB    STOP
        BNEQ    900$
        INCL    R5
        SOBGTR  R5,870$
        BSBW    COMPNXT
        BLBC    R0,900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  DATE - Display in system date format
DATE::
        BSBW    SETUP
        BLBS    R0,100$
        BRW     900$
100$:
        TSTL    REM
        BLEQ    110$
        BSBW    INVPARA
        BRW     900$
110$:
        DIVL2   DSPCNT,R5
120$:
        MOVL    PARA1,R3
        BSBW    NUMOUT
        ADDL2   #8,PARA1
        MOVB    #^A/ /,(R6)+
        TSTL    4(R4)
        BGTR    200$
        BLSS    150$
        TSTL    (R4)
        BNEQ    200$
150$:
        PUSHR   #^M<R4,R5>
        MOVC3   #IVTL,IVT,(R6)
        POPR    #^M<R4,R5>
        ADDL2   #IVTL,R6
        BRB     300$
200$:
        MOVL    #30,OUTDSCV
        MOVL    R6,OUTDSCV+4
        $ASCTIM_S  TIMLEN=OUTDSCV,TIMBUF=OUTDSCV,TIMADR=(R4)
        BLBS    R0,250$
        BSBW    ERROUT
        BRW     900$
250$:
        CVTWL   OUTDSCV,R1
        ADDL2   R1,R6
300$:
        ADDL2   #8,R4
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        TSTB    STOP
        BNEQ    900$
        SOBGTR  R5,800$
        BRB     900$
800$:
        BRW     120$
900$:
        RSB
        .PAGE
        .SBTTL  RECORD - Display sequential records
RECORD::
        TSTB    SEQFLG
        BEQL    50$
        BSBW    ZEROBLK
        BLBS    R0,100$
50$:
        OUTMSG  #NSFL,NSF
        BRW     900$
100$:
        ADDL3   #1,CURBCT,EOFBYTE
        SUBL3   CURBLK,EFBLK,R1
        BLSS    110$
        MULL2   #512,R1
        CMPL    R1,CURBCT
        BGEQ    120$
        ADDL3   R1,FFBYTE,EOFBYTE
        BGTR    120$
110$:
        OUTMSGC EOF
        BRW     900$
120$:
        CMPL    PARA1,CURBCT
        BGEQ    122$
        CMPL    PARA2,#0
        BNEQ    124$
122$:
        BSBW    INVPARA
        MNEGL   #1,RECPTR
        BRW     900$
124$:
        ADDL3   RSIZE,VFCSIZE,MAXREC
        MOVL    #132,RECWID
        TSTW    TERMON
        BEQL    1245$
        MOVL    TERMWD,RECWID
1245$:
        TSTL    PARA1
        BLSS    1247$
        BRW     126$
1247$:
        TSTL    PARA2
        BGTR    125$
        MOVL    RECCNT,PARA2
125$:
        MOVL    RECPTR,PARA1
        BLSS    1252$
        CMPL    RECPTR,CURBCT
        BLEQ    126$
1252$:
        TSTB    VFLAG
        BNEQ    128$
        CLRL    PARA1
        TSTB    NOSPNFLG
        BNEQ    126$
        SUBL3   #1,CURBLK,R2
        MULL2   #512,R2
        CLRL    R3
        MOVL    MAXREC,R1
        BLBC    R1,1255$
        INCL    R1
1255$:
        EDIV    R1,R2,R0,R3
        TSTL    R3
        BEQL    126$
        SUBL3   R3,MAXREC,PARA1
        CMPL    PARA1,CURBCT
        BLSS    126$
        BRW     160$
126$:
        BRW     180$
128$:
        CLRL    R4
        CMPL    CURBLK,#1
        BGTR    129$
        BRW     175$
129$:
        SUBL3   #2,EOFBYTE,R2
        DIVL3   #2,EOFBYTE,R3
130$:
        MOVZWL  BUFF(R4),R7
        MOVL    R4,R8
140$:
        CMPL    R7,MAXREC
        BGTR    150$
        ADDL2   #2,R7
        BLBC    R7,145$
        INCL    R7
145$:
        ADDL2   R7,R8
        CMPL    R8,R2
        BGEQ    170$
        MOVZWL  BUFF(R8),R7
        CMPL    R7,#^XFFFF
        BNEQ    140$
        BRB     170$
150$:
        ADDL2   #2,R4
        SOBGTR  R3,130$
160$:
        OUTMSG  #CNDL,CNDRSM
        BRW     900$
170$:
        CMPL    MAXREC,#140
        BLEQ    175$
        OUTMSG  #LRLL,LRLMSG
175$:
        MOVL    R4,PARA1
180$:
        ADDL3   #BUFF,PARA1,R4
        SUBL3   PARA1,CURBCT,R5
        MOVL    PARA2,R8
        BGTR    185$
        MOVL    #1,R8
185$:
        MOVL    R8,RECCNT
        CLRL    HDRCNT
        CLRL    R2
        TSTB    HDRFLG
        BEQL    190$
        MOVL    VFCSIZE,R2
        CMPL    R2,#8
        BLEQ    190$
        MOVL    #8,R2
190$:
        MOVL    R2,VFCOUT
        SUBL3   #1,R2,VFCOUTM1
        SUBL3   R2,VFCSIZE,VFCSKIP
250$:
        BLBC    R4,280$
        INCL    R4
        DECL    R5
280$:
        TSTL    R5
        BGTR    300$
290$:
        BSBW    RECNXT
        BLBS    R0,300$
        BRW     900$
300$:
        SUBL3   #BUFF,R4,R3
        MOVL    R3,RECPTR
        CMPL    R3,EOFBYTE
        BLSS    310$
        OUTMSGC EOF
        BRW     900$
310$:
        MOVAL   OUT_BUFF,R6
        TSTB    HDRFLG
        BEQL    315$
        MOVL    #6,HDRCNT
        BSBW    NUMOUT
315$:
        MOVL    VFCOUT,R10
        TSTB    VFLAG
        BNEQ    320$
        MOVL    MAXREC,R7
        BRW     400$
320$:
        SUBL2   #2,R5
        CVTWL   (R4)+,R7
        BGEQ    350$
        TSTB    NOSPNFLG
        BEQL    340$
        CMPL    CURBLK,EFBLK
        BGEQ    340$
        CLRL    R5
        BRW     290$
340$:
        MOVC3   #7,EOF,(R6)
        ADDL2   #7,R6
        BRB     380$
350$:
        CMPL    R7,MAXREC
        BLEQ    400$
        MNEGL   #1,RECPTR
        MOVL    #80,OUTDSCV
        MOVL    R6,OUTDSCV+4
        $FAO_S  CTRSTR=MAXMSG,OUTLEN=OUTDSCV,OUTBUF=OUTDSCV,-
                P1=R7,P2=RSIZE
        CVTWL   OUTDSCV,R3
        ADDL2   R3,R6
380$:
        SUBL2   #OUT_BUFF,R6
        OUTMSG  R6,OUT_BUFF
        BRW     900$
400$:
        SUBL3   HDRCNT,RECWID,R9
        TSTB    HDRFLG
        BNEQ    410$
        ADDL2   VFCSIZE,R4
        SUBL2   VFCSIZE,R5
        SUBL2   VFCSIZE,R7
        BLEQ    420$
        TSTL    R5
        BGTR    420$
        BRW     610$
410$:
        MOVB    #^A/ /,(R6)+
420$:
        TSTB    STOP
        BEQL    450$
        BRW     900$
450$:
        TSTL    R7
        BLEQ    460$
        TSTL    R5
        BGTR    480$
        TSTB    HDRFLG
        BNEQ    460$
        BSBW    RECNXT
        BLBS    R0,480$
        BRW     900$
460$:
        BRW     600$
480$:
        DECL    R7
        DECL    R5
        SOBGEQ  R10,482$
        BRW     490$
482$:
        CMPL    R10,VFCOUTM1
        BLSS    485$
        DECL    R6
        MOVB    #^A/</,(R6)+
485$:
        EXTZV   #4,#4,(R4),R3
        MOVB    HEXD[R3],(R6)+
        DECL    R9
        EXTZV   #0,#4,(R4)+,R3
        MOVB    HEXD[R3],(R6)+
        TSTL    R10
        BGTR    488$
        MOVB    #^A/>/,(R6)+
        MOVB    #^A/ /,(R6)+
        SUBL3   #OUT_BUFF,R6,HDRCNT
        SUBL2   #2,R9
        ADDL2   VFCSKIP,R4
        SUBL2   VFCSKIP,R5
        SUBL2   VFCSKIP,R7
488$:
        BRB     580$
490$:
        MOVZBL  (R4)+,R3
        TSTB    EBCFLG
        BEQL    491$
        MOVB    EBCTBL[R3],(R6)+
        BRB     580$
491$:
        TSTB    HDRFLG
        BNEQ    495$
        CMPB    R3,#^X09
        BNEQ    495$
        SUBL3   #OUT_BUFF,R6,R2
        CLRL    R3
        EDIV    #8,R2,R0,R1
        SUBL3   R1,#8,R3
492$:
        MOVB    #^A/ /,(R6)+
        SOBGTR  R3,493$
        BRB     580$
493$:
        SOBGTR  R9,492$
        BRB     600$
495$:
        CMPB    R3,#32
        BLSS    500$
        CMPB    R3,#127
        BNEQ    550$
500$:
        MOVB    #^A/./,R3
550$:
        MOVB    R3,(R6)+
580$:
        SOBGTR  R9,590$
        BRB     600$
590$:
        BRW     450$
600$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        TSTL    R7
        BLEQ    750$
        TSTL    R5
        BGTR    700$
610$:
        BSBW    RECNXT
        BLBS    R0,700$
        BRB     900$
700$:
        TSTL    R9
        BGTR    720$
        SUBL3   HDRCNT,RECWID,R9
720$:
        SUBL3   R9,RECWID,R6
        BEQL    740$
        PUSHR   #^M<R4,R5>
        MOVC5   #0,OUT_BUFF,#^A/ /,R6,OUT_BUFF
        POPR    #^M<R4,R5>
740$:
        ADDL2   #OUT_BUFF,R6
        BRW     420$
750$:
        SOBGTR  R8,800$
        SUBL3   #BUFF,R4,RECPTR
        BRB     900$
800$:
        BRW     250$
900$:
        RSB

RECNXT:
        DIVL3   #512,CURBCT,R1
        ADDL2   CURBLK,R1
        CMPL    R1,EFBLK
        BGTR    100$
        BLSS    200$
        TSTL    FFBYTE
        BGTR    200$
100$:
        OUTMSGC EOF
        CLRL    R0
        BRB     900$
200$:
        MOVL    #1,PARA1
        BSBW    NEXT
        BLBC    R0,900$
        TSTB    HDRFLG
        BEQL    350$
        BSBW    BLOCK
350$:
        ADDL3   #1,CURBCT,EOFBYTE
        SUBL3   CURBLK,EFBLK,R1
        MULL2   #512,R1
        CMPL    R1,CURBCT
        BGEQ    400$
        ADDL3   R1,FFBYTE,EOFBYTE
400$:
        SUBL3   R5,#BUFF,R4
        ADDL2   CURBCT,R5
900$:
        RSB
        .PAGE
        .SBTTL  DIFF - Display differences with paste buffer
DIFF::
        TSTL    CURBCT
        BGTR    20$
        OUTMSGC CBEMPTY
        BRW     900$
20$:
        TSTL    PBBCT
        BGTR    30$
        OUTMSGC PBEMPTY
        BRW     900$
30$:
        BSBW    SETUP
        BLBS    R0,50$
        BRW     900$
50$:
        TSTL    REM
        BLEQ    100$
        BSBW    INVPARA
        BRW     900$
100$:
        MOVAL   PBUFF,R9
        CMPL    R5,PBBCT
        BLEQ    120$
        MOVL    #80,OUTDSC
        $FAO_S  CTRSTR=PBTRUNC,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=PBBCT
        OUTMSG  OUTDSC,OUT_BUFF
        MOVL    PBBCT,R5
120$:
        CMPC3   R5,(R4),(R9)
        CMPL    R0,#0
        BGTR    150$
        OUTMSG  #NDIFFL,NDIFF
        BRW     900$
150$:
        MOVL    #4,R1
        BSBW    ALIGN
200$:
        MOVB    #0,FLAG
        MOVL    PARA2,R3
        BSBW    NUMOUT
        ADDL2   LC3248,PARA2
        MOVQ    R4,R4R5S
        MOVQ    R9,R9R10S
        MOVL    #1,R11
        BRB     280$
250$:
        MOVC3   #5,PBOUT,OUT_BUFF
        MOVAL   OUT_BUFF+5,R6
        MOVQ    R4R5S,R4
        MOVQ    R9R10S,R9
280$:
        MOVL    LC0812,R8
300$:
        MOVL    #4,R7
        MOVB    #^A/ /,(R6)+
400$:
        SOBGEQ  R10,500$
        MOVL    R4,R3
        CMPB    (R4)+,(R9)+
        BNEQ    450$
        BLBS    R11,480$
        MOVW    #^A/../,(R6)+
        BRB     600$
450$:
        MOVB    #1,FLAG
        BLBS    R11,480$
        SUBL3   #1,R9,R3
480$:
        EXTZV   #4,#4,(R3),R1
        MOVB    HEXD[R1],(R6)+
        EXTZV   #0,#4,(R3),R1
        MOVB    HEXD[R1],(R6)+
        BRB     600$
500$:
        MOVW    #^A/  /,(R6)+
600$:
        SOBGTR  R5,700$
        BRB     800$
700$:
        SOBGTR  R7,400$
        SOBGTR  R8,300$
800$:
        CMPB    #0,FLAG
        BEQL    850$
        BLBS    R11,810$
        MOVB    #LF,(R6)+
810$:
        SUBL2   #OUT_BUFF,R6
        OUTPUT  R6,OUT_BUFF
        SOBGEQ  R11,830$
        BRB     850$
830$:
        BRW     250$
850$:
        CMPB    STOP,#0
        BNEQ    900$
        ADDL2   #1,R5
        SOBGTR  R5,870$
        BRB     900$
870$:
        BRW     200$
900$:
        RSB
        .PAGE
        .SBTTL  Miscellaneous utility routines

SETUP:
        TSTB    DPBFLG
        BNEQ    40$
        BSBW    ZEROBLK
        BLBS    R0,20$
        BRW     900$
20$:
        MOVL    CURBCT,DSPBCT
        ADDL3   #1,PARA2,R1
        BNEQ    50$
        DIVL3   DSPCNT,CURBCT,PARA2
        BRB     50$
40$:
        MOVL    PBBCT,DSPBCT
        BGTR    50$
        OUTMSGC PBEMPTY
        CLRL    R0
        BRW     900$
50$:
        CMPL    PARA1,DSPBCT
        BGEQU   100$
        CMPL    PARA2,#0
        BGTR    200$
100$:
        BSBW    INVPARA
        BRW     900$
200$:
        MOVAL   LC80,R4
        MOVL    #16,WLINC
        MOVL    WLPARM,WLCNT
        CMPL    TERMWD,#132
        BGEQ    250$
        TSTW    TERMON
        BNEQ    300$
250$:
        MULL2   #2,WLINC
        MULL2   #2,WLCNT
        MOVAL   LC132,R4
300$:
        MOVQ    (R4),LCBEGN
        MOVQ    8(R4),LCBEGN+8
        MULL2   DSPCNT,PARA2
        ADDL3   PARA1,PARA2,R3
        SUBL3   DSPBCT,R3,REM
        BLEQ    400$
        MOVL    DSPBCT,R3
400$:
        ADDL3   #BUFF,PARA1,R4
        TSTB    DPBFLG
        BEQL    500$
        TSTL    REM
        BLEQ    450$
        BSBW    INVPARA
        BRB     900$
450$:
        OUTPUT  #PBCL,PBCON
        ADDL3   #PBUFF,PARA1,R4
500$:
        SUBL3   PARA1,R3,R5
        MOVL    #1,R0
900$:
        RSB

ALIGN:
        DIVL3   R1,PARA1,R3
        MULL2   R1,R3
        MOVL    R3,PARA2
        SUBL3   R3,PARA1,R10
        ADDL2   R10,R5
        RSB

COMPNXT:
        CLRL    R0
        CMPL    REM,#0
        BLEQ    900$
        MOVL    #1,PARA1
        BSBW    NEXT
        BLBC    R0,900$
        BSBW    BLOCK
        MOVAL   BUFF,R4
        CLRL    PARA1
        CLRL    PARA2
        CLRL    R10
        CMPL    REM,CURBCT
        BGTR    200$
        MOVL    REM,R5
        CLRL    REM
        BRB     900$
200$:
        SUBL2   CURBCT,REM
        MOVL    CURBCT,R5
900$:
        RSB
        .PAGE
NUMOUT:
        PUSHR   #^M<R4,R5>
        CLRQ    R4
        MOVAL   OUT_BUFF,R6
        TSTB    TAPFLG
        BNEQ    100$
        TSTB    DPBFLG
        BNEQ    100$
        CMPL    BUFFCT,#1
        BEQL    120$
100$:
        INCL    R5
120$:
        TSTB    HEXFLG
        BNEQ    200$
        BLBC    R5,150$
        EDIV    #10000,R3,R2,R3
        EDIV    #1000,R3,R2,R3
        ADDB3   R2,#^A/0/,(R6)+
150$:
        EDIV    #100,R3,R2,R3
        ADDB3   R2,#^A/0/,(R6)+
        EDIV    #10,R3,R2,R3
        ADDB3   R2,#^A/0/,(R6)+
        ADDB3   R3,#^A/0/,(R6)+
        BRB     300$
200$:
        BLBC    R5,250$
        EXTZV   #12,#4,R3,R2
        MOVB    HEXD[R2],(R6)+
250$:
        EXTZV   #8,#4,R3,R2
        MOVB    HEXD[R2],(R6)+
        EXTZV   #4,#4,R3,R2
        MOVB    HEXD[R2],(R6)+
        EXTZV   #0,#4,R3,R2
        MOVB    HEXD[R2],(R6)+
300$:
        MOVB    #^A/:/,(R6)+
        BLBS    R5,320$
        MOVB    #^A/ /,(R6)+
320$:
        POPR    #^M<R4,R5>
        RSB
        .PAGE
        .SBTTL  Data definitions

        .PSECT  DATA,WRT,NOEXE

LF=^X0A

NDIFF:  .ASCII  /No differences./
NDIFFL=.-NDIFF

NSF:    .ASCII  /File must be SEQUENTIAL in order to use this command./
NSFL=.-NSF

CNDRSM: .ASCII  /Can not determine record start address in this block/
CNDL=.-CNDRSM

LRLMSG: .ASCII  /**Auto record locate is unpredictable with /
        .ASCII  /large V-length records**/
LRLL=.-LRLMSG

MAXMSG: .ASCID  /**Record size of !UL exceeds maximum allowed (!UL)**/

IVT:    .ASCII  /Invalid date-time format/
IVTL=.-IVT

PBCON:  .ASCII  /      Paste buffer contents:/
PBCL=.-PBCON

PBTRUNC: .ASCID /Comparison truncated to paste buffer length (!UL bytes)/

HEXD::  .ASCII  /0123456789ABCDEF/

SP5:    .ASCII  /     /
PBOUT:  .ASCII  /*PB* /
EOF:    .ASCIC  /**EOF**/

EBCTBL: .ASCII  /................/ ; HEX 00 - 0F
        .ASCII  /................/ ; HEX 10 - 1F
        .ASCII  /................/ ; HEX 20 - 2F
        .ASCII  /................/ ; HEX 30 - 3F
        .ASCII  / .........[.<(+!/ ; HEX 40 - 4F
        .ASCII  /&.........]$*);^/ ; HEX 50 - 5F
        .ASCII  \-/........|,%_>?\ ; HEX 60 - 6F
        .ASCII  /.........`:#@'="/ ; HEX 70 - 7F
        .ASCII  /.abcdefghi....../ ; HEX 80 - 8F
        .ASCII  /.jklmnopqr....../ ; HEX 90 - 9F
        .ASCII  /.~stuvwxyz....../ ; HEX A0 - AF
        .ASCII  /................/ ; HEX B0 - BF
        .ASCII  /{ABCDEFGHI....../ ; HEX C0 - CF
        .ASCII  /}JKLMNOPQR....../ ; HEX D0 - DF
        .ASCII  /\.STUVWXYZ....../ ; HEX E0 - EF
        .ASCII  /0123456789....../ ; HEX F0 - FF

LC80:   .LONG   64,32,16,8
LC132:  .LONG   96,48,24,12
LCBEGN:
LC6496: .LONG   0
LC3248: .LONG   0
LC1624: .LONG   0
LC0812: .LONG   0
OUTDSCV: .QUAD  0
DSPBCT: .LONG   0
REM:    .LONG   0
;
; Used by IWLDSP
;
OVERFL: .LONG   0
SVSTAT: .LONG   0
DSPCNT:: .LONG  0
WLINC:  .LONG   0
WLCNT:  .LONG   0
WLPARM:: .LONG  0
WLPOSN:: .LONG  0
;
; Used by DIFF and MULTI
;
R4R5S:  .QUAD   0
R9R10S: .QUAD   0
FLAG:   .BYTE   0
;
; Used by RECORD
;
RECPTR:: .LONG  -1
RECCNT: .LONG   1
HDRCNT: .LONG   0
RECWID: .LONG   0
VFCOUT: .LONG   0
VFCOUTM1: .LONG 0
VFCSKIP: .LONG  0
MAXREC: .LONG   0
EOFBYTE: .LONG  0

        .END
$*$*EOD*$*$
$ checksum DISPLAY.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ check_sum = 645546437
$ write sys$output "Creating VFELIB.MAR"
$ create VFELIB.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .MACRO  INPUT   ARG1,ARG2,ARG3,ARG4
        CVTWL   ARG3,-(SP)
        PUSHAL  ARG4
        CVTWL   ARG1,-(SP)
        PUSHAL  ARG2
        CALLS   #4,TERMIO
        .ENDM

        .MACRO  OUTPUT  ARG1,ARG2
        CVTWL   ARG1,-(SP)
        PUSHAL  ARG2
        CALLS   #2,TERMIO
        .ENDM

        .MACRO  OUTMSG  ARG1,ARG2
        PUSHL   #1
        CVTWL   ARG1,-(SP)
        PUSHAL  ARG2
        CALLS   #3,TERMIO
        .ENDM

        .MACRO  OUTMSGC ARG1
        PUSHL   #1
        MOVZBL  ARG1,-(SP)
        PUSHAL  ARG1+1
        CALLS   #3,TERMIO
        .ENDM
$*$*EOD*$*$
$ checksum VFELIB.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ exit

PORTIA@ENGVAX.SCG.HAC.COM (Portia 616-2635) (07/25/87)

$ show default
$ check_sum = 824401541
$ write sys$output "Creating VFE.MAR"
$ create VFE.MAR
$ DECK/DOLLARS="$*$*EOD*$*$"
        .TITLE  VFE VMS File Editor

        .IDENT  /MCCCD VFE V2.0/

        .SBTTL  Introduction
;
; VMS File Editor, Version 2.0
;
;     Written at MCCCD by Ward Condit, spring 1984
;     (Enhanced, fall 1985)
;
;     Inspired by fond remembrances of Sperry 1100 "FILEDIT",
;     written at the U of Maryland by B. K. Reid and K. E. Sibbald
;
;     Helpful hints and suggestions provided by:
;                           Jason Pociask
;                           Chris Zagar
;                           David Mitchell
;
; VFE is a utility which allows a user to perform display,
; change, locate, and compare operations on any VMS file, disk
; device, or tape that the user has privilege to access.
; VFE is block-oriented and independent of file type.
;
; Version 2.0 has limited source documentation.  VFE will soon
; be submitted to the DECUS program library with full source docs.
;
; This software is provided free of charge in the PUBLIC DOMAIN
; by the Maricopa Community Colleges.  By accepting this software
; the user agrees not to hold the supplier liable for damages of
; any kind, resulting either from software errors or improper
; operation.
;
; It is STRONGLY SUGGESTED that VFE be operated ONLY in read-only
; mode when examining system files.  Read-only mode should also be
; used when editing other critical files for which there is no
; current backup.


LOCSIZ=50       ; Buffer size (blocks) for the LOCATE command
                ; This also represents the maximum SET BUFF size.

MAXBCT==30000   ; Max block size (bytes) for tape read
                ;  (must be >= LOCSIZ*512)

        .ENABLE SUPPRESSION

        .LIBRARY  'VFELIB'

        $HLPDEF

LF=^X0A
        .PAGE
        .SBTTL  Main program
;
; This is the initialization and main control loop code.
;
        .PSECT  CODE,EXE,NOWRT

        .ENTRY  START,0

        BSBW    TINIT                   ; set up user interface I/O
        BLBS    R0,100$                 ; better have good status here
        $EXIT_S CODE=R0                 ;  or stop right now.
100$:
        MOVL    TERMWD,INITWID          ; save initial terminal width
        $ASCTIM_S  TIMBUF=SGNTIM        ; get system time for signon msg
        OUTMSG  #SGNL,SIGNON            ; display signon message
        PUSHAW  DESC
        PUSHAL  FNQ
        PUSHAL  DESC
        CALLS   #3,G^LIB$GET_FOREIGN    ; get user-supplied params
        BLBS    R0,200$
        BRB     800$                    ; exit if error returned
200$:
        BSBW    GETFILE                 ; open first file for edit
;
; This is the main control loop.
;
300$:
        BSBW    GETCMD                  ; input and parse command line
        CLRB    STOP                    ; clear control_c flag
        MOVL    JMPADR,R1
        JSB     (R1)                    ; branch to desired routine
        BRB     300$                    ; get next command when done
;
; error returned from LIB$GET_FOREIGN
;
800$:
        CMPL    R0,#RMS$_EOF            ; end-of file?
        BNEQ    900$
        BRW     EXIT                    ; if so, exit quietly
900$:
        BRW     ERREXT                  ; otherwise, display error and exit
        .PAGE
        .SBTTL  CHANGE - Change one or more sequential bytes
CHANGE::
        TSTL    PARA1                   ; test byte address to change
        BLSS    100$                    ; error if negative
        MOVZWL  QDESC,R1                ; get length of change-string
        ADDL2   PARA1,R1                ; add byte address
        CMPL    R1,CURBCT
        BLEQ    200$                    ; OK if fits within current buffer
        TSTL    CURBCT                  ;  nope - test buffer size
        BGTR    100$                    ; if nonzero, "invalid parameter(s)"
        OUTMSGC CBEMPTY                 ; otherwise, "current buffer empty"
        BRW     600$
100$:
        BSBW    INVPARA                 ; output error message and exit
        BRW     600$
;
; At this point the parameters have been validated.
;
200$:
        MOVAL   BUFF,R6
        ADDL2   PARA1,R6                ; R6 = address of first byte to change
        MOVC3   QDESC,@QDESC+4,CSTR     ; move to change-string save area
        MOVZWL  QDESC,CSTRL             ; save length
        MOVB    QTYPE,CSTRT             ;  and type (0=char, 1,2=dec, 3=hex)
        BNEQ    300$                    ; skip if non-character
        TSTB    EBCFLG                  ; if char string, is charset=ebcdic?
        BNEQ    400$                    ; yes - go translate
300$:
        MOVC3   CSTRL,CSTR,(R6)         ; move change-string to buffer
        BRB     500$
400$:
        MOVW    CSTRL,DESC
        MOVL    R6,DESC+4               ; set up DESC to point to buffer
        PUSHAL  DESC
        PUSHAL  QDESC
        CALLS   #2,G^LIB$TRA_ASC_EBC    ; trans to EBCDIC straight into buff
        BLBS    R0,500$
        BSBW    ERROUT                  ; indicate error if necessary
500$:
        CLRL    LPTR                    ; zero LOCATE pointer after change
        MOVL    CURBLK,CHGBLK
        MOVL    PARA1,CHGBYT            ; save block, byte, and
        MOVC3   CURNAM,CURNAM,CHGNAM    ;   file name for SHOW CHANGE
600$:
        RSB
        .PAGE
        .SBTTL  CUT - Transfer current buff to paste buff
;
; Processing for the CUT command.
;
CUT::
        BSBW    CPINIT                  ; call cut/paste init
        BLBS    R0,100$
        BRB     200$                    ; don't cut if error
100$:
        MOVC3   PARA2,(R4),PBUFF        ; move selected data to paste buffer
        MOVL    PARA1,PBOFF             ; save offset (beginning byte) addr
        MOVL    PARA2,PBBCT             ; save byte count
        MOVL    CURBLK,PSTBLK
        MOVC3   CURNAM,CURNAM,PSTNAM    ; save block, file for SHOW PASTE
200$:
        RSB


        .SBTTL  PASTE - Transfer paste buff to current buff
;
; Processing for the PASTE command.
;
PASTE::
        BSBW    CPINIT                  ; call cut/paste init
        BLBS    R0,100$
        BRW     900$                    ; don't paste if error
100$:
        TSTL    PBBCT                   ; test paste buffer size
        BGTR    200$
        OUTMSGC PBEMPTY                 ; output err msg and quit if empty
        BRW     900$
200$:
        SUBL3   PBBCT,PARA2,R1          ; R1 = excess bytes in PASTE range
        BLEQ    300$
        MOVL    #80,OUTDSC              ; if > zero, output "zero fill" msg
        $FAO_S  CTRSTR=PBSMALL,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=PBBCT,P2=R1
        OUTMSG  OUTDSC,OUT_BUFF
        BRB     400$
300$:
        BEQL    400$
        MOVL    #80,OUTDSC              ; if < zero, output "truncated" msg
        $FAO_S  CTRSTR=PBLARGE,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=PBBCT,P2=PARA2
        OUTMSG  OUTDSC,OUT_BUFF
400$:
        MOVC5   PBBCT,PBUFF,#0,PARA2,(R4)  ; move selected data to curr buff
        CLRL    LPTR                    ; clear the LOCATE pointer
        MNEGL   #1,RECPTR               ;  and the RECORD pointer
900$:
        RSB
        .PAGE
;
; This routine called by CUT and PASTE to validate user range
;
CPINIT:
        TSTL    CURBCT                  ; test size of current buffer
        BGTR    100$
        OUTMSGC CBEMPTY                 ; output "empty" message if empty
        BRB     300$
100$:
        ADDL3   PARA1,PARA2,R1          ; R1 = ending byte + 1
        CMPL    R1,CURBCT
        BGTR    200$                    ; error if exceeds current buff size
        TSTL    PARA2
        BLEQ    200$                    ; error if transfer count < 1
        ADDL3   #BUFF,PARA1,R4          ; setup R4 = address to begin transfer
        MOVL    #1,R0                   ; indicate good return status
        BRB     400$
200$:
        BSBW    INVPARA                 ; output "invalid parameter" message
300$:
        CLRL    R0                      ; error status
400$:
        RSB
        .PAGE
        .SBTTL  LOCATE - Search for a specified target
LOCATE::
        TSTL    CURBCT                  ; check size of current buffer
        BGTR    50$                     ; skip if nonzero
        MOVL    #1,PARA1
        BSBW    NEXT                    ; read next block of file
        BLBS    R0,50$                  ; Check status
        BRW     980$                    ; Abort locate if error
50$:
        MOVL    QDESC+4,R7              ; R7 = addr of parameter string
        CMPW    LSTRL,QDESC             ; compare length with prev string
        BNEQ    100$                    ; skip compare if unequal
        CMPB    QTYPE,LSTRT             ; same types? 0=char, 1,2=dec, 3=hex
        BNEQ    100$                    ; no, skip compare
        CMPC3   LSTRL,(R7),LSTR         ; compare equal-length strings
        BNEQ    100$                    ; skip if not the same
        CMPL    LPTR,CURBCT             ; does locate ptr exceed curr buff?
        BLEQ    200$                    ; nope - begin processing
        BRB     190$                    ; yes - zero pointer (same string)
100$:
        MOVC3   QDESC,(R7),LSTR         ; move new parameter to save location
        MOVZWL  QDESC,LSTRL             ; move new length
        MOVB    QTYPE,LSTRT             ; move new parameter type
        CLRW    LOCNAM
190$:
        CLRL    LPTR                    ; begin search at top of buffer
200$:
        MOVC3   LSTRL,LSTR,LSTRX        ; move locate string to LSTRX
        MOVB    LSTRT,LOCSFL            ; move type - check for char string
        BEQL    220$
        BRW     300$                    ; not string - skip EBCDIC check
220$:
        TSTB    EBCFLG                  ; does charset=ebcdic?
        BEQL    240$                    ; nope
        MOVW    LSTRL,DESC              ; yes - set up for translate
        MOVAL   LSTRX,DESC+4
        PUSHAL  DESC
        PUSHAL  QDESC
        CALLS   #2,G^LIB$TRA_ASC_EBC    ; LSTRX now in EBCDIC
        BLBS    R0,240$
        BSBW    ERROUT                  ; display error msg and quit if error
        BRW     980$
240$:
        MOVB    CASFLG,LOCSFL           ; LOCSFL=0 if char str and SET NOCASE
        BNEQ    300$                    ; skip translate if LOCSFL>0
        MOVW    LSTRL,DESC              ;
        MOVAL   LSTRX,DESC+4            ;
        MOVW    LSTRL,UDESC             ; set up for translate
        MOVAL   LSTRX,UDESC+4           ;
        BSBW    UPCASE                  ; translate LSTRX to uppercase
        BLBS    R0,300$                 ;
        BSBW    ERROUT                  ; error in translation -
        BRW     980$                    ;  so indicate and exit
        .PAGE
;
;        Prepare to search the current buffer for the target.
;
300$:
        ADDL3   #BUFF,LPTR,R7           ; R7 = byte address to begin search
        CLRL    FNDCNT                  ; zero match count
        CLRB    FLAG                    ; zero "replace buffer contents" flag
        CLRB    BSFLAG                  ; initialize backspace flag
        ADDL3   #1,CURBLK,LBLOCK        ; initialize LBLOCK for match rtn
        CLRL    LBLKCT                  ; init block count (nothing read yet)
        SUBL3   LPTR,CURBCT,R8          ; R8 = bytes remaining to search in BUFF
        CMPL    LSTRL,R8                ; compare with target string length
        BGTR    400$                    ; skip if not enough to search
        SUBL3   #1,LSTRL,REMCT          ; REMCT = carry-forward byte count
                                        ;  for next search
        BSBW    MATCHIT                 ; call match routine to do the search
        BLBC    R0,380$                 ; internal error - exit
        BLBC    R1,420$                 ; skip if no match or global search
380$:
        BRW     970$                    ;  otherwise, exit
400$:
        MOVL    R8,REMCT                ; init REMCT for short rem count
420$:
        TSTB    STOP                    ; test if control_c entered yet
        BEQL    430$
        BRW     970$                    ; yes - abort search
430$:
        TSTB    TAPFLG                  ; editing tape?
        BNEQ    500$                    ; yes - skip
        MOVC3   CURBCT,BUFF,SBUFF       ; no - move curr buff to SBUFF
        MOVL    CURBCT,SAVBCT           ;  and save buffer size
        SUBL3   #512,CURBCT,R1
        BEQL    500$                    ; skip if buff size is one block
        MOVC3   #512,BUFF(R1),BUFF      ; otherwise move last block to top
        DIVL3   #512,CURBCT,R1
        ADDL3   R1,CURBLK,LBLOCK        ; set up LBLOCK for next block
        MOVL    #512,CURBCT             ; CURBCT must = 512 for disk locate
        .PAGE
;
;       This is the top of the locate loop.
;
500$:
        TSTB    TAPFLG                  ; is this a tape file?
        BEQL    510$                    ;  no, continue
        BRW     600$                    ;  yes - skip to tape code
510$:
        MOVL    #LOCSIZ,LBLKCT          ; init length for normal-size read
        SUBL3   LBLOCK,HIBLK,R4         ; R4 = blocks remaining minus 1
        BGEQ    520$                    ; if >= zero, continue
        MOVL    SAVBCT,CURBCT           ; search complete - restore saved CURBCT
        TSTB    FLAG                    ; test "modified" flag
        BEQL    515$                    ; skip if 0
        MOVC3   CURBCT,SBUFF,BUFF       ; otherwise, restore buffer contents
        CLRB    FLAG                    ; zero flag
515$:
        BRW     800$                    ; exit "no find"
520$:
        CMPL    R4,LBLKCT               ; test for fewer than default blocks
        BGEQ    530$                    ;  remaining to be searched
        ADDL3   #1,R4,LBLKCT            ; if so, move rem blk count to LBLKCT
530$:
        MULL3   #512,LBLKCT,R2          ; R2 = bytes to read
        MOVL    LBLOCK,R1               ; R1 = block address in file
        BSBW    READINT                 ; read into BUFF+512
        MOVL    #512,LSTBCT             ; init LSTBCT for disk
        MOVL    R0,SVSTAT               ; save return status
        BLBS    R0,650$                 ; skip if normal
        CMPL    NXTBCT,#512             ; error status - check for at least
        BGEQ    650$                    ;  one full block read
        BRW     670$                    ;  if not, skip search
600$:
        MOVL    #1,LBLKCT               ; init LBLKCT for tape
        MOVB    #1,BSFLAG               ; set backspace flag
        BSBW    READINT                 ; read next block into BUFF+CURBCT
        BLBS    R0,620$                 ; skip if normal status
        CMPL    R0,#SS$_ENDOFFILE       ; test for end of file
        BEQL    610$                    ; this is normal exit status
        BSBW    ERROUT                  ; abnormal status - show to user
        SUBL3   #1,LBLOCK,CURBLK        ; compute current block number
        BRW     900$                    ; exit
610$:
        SUBL3   #1,LBLOCK,CURBLK        ; compute current block number
        BRW     800$                    ; exit "no find" or end global search
620$:
        MOVL    #1,SVSTAT               ; set good status
        MOVL    NXTBCT,LSTBCT           ; init LSTBCT for tape
650$:
        ADDL3   #BUFF,CURBCT,R7         ;
        SUBL2   REMCT,R7                ; R7 = address to begin search
        ADDL3   NXTBCT,REMCT,R8         ; R8 = byte count to search
        BSBW    MATCHIT                 ; call match routine
        BLBS    R0,660$                 ; check for internal error
        SUBL3   #1,LBLOCK,CURBLK        ; if error, compute current block
        BRW     900$                    ;  data in BUFF, update CURBLK and exit
660$:
        BLBC    R1,670$                 ; skip if no match or global search
        BRW     700$                    ;  otherwise, exit
670$:
        MOVL    SVSTAT,R0               ; restore status from read operation
        BLBS    R0,690$                 ; skip if normal
        BSBW    ERROUT                  ; otherwise, indicate error and...
        DIVL3   #512,NXTBCT,R4          ;  compute R4 = full blocks read
        ADDL3   LBLOCK,R4,R5            ;  R5 = address + 1 of last good block
        SUBL3   #1,R5,CURBLK            ;  update CURBLK accordingly
        MULL2   #512,R4                 ;  R4 = byte offset from BUFF to move
        BEQL    680$                    ;  skip if zero
        MOVC3   #512,BUFF(R4),BUFF      ;  move last good data to BUFF
        INCB    FLAG                    ;  set "buffer modified" flag
680$:
        BRW     900$                    ;  exit
690$:
        MULL3   CURBCT,LBLKCT,R6        ; R6 = bytes last read
        MOVC3   LSTBCT,BUFF(R6),BUFF    ; move last block data to BUFF
        MOVL    LSTBCT,CURBCT           ; update CURBCT
        CLRB    BSFLAG                  ; zero backspace flag
        MOVB    #1,FLAG                 ; set "buffer modified" flag
        SUBL3   #1,LSTRL,REMCT          ; remaining ct = string ct - 1
        ADDL2   LBLKCT,LBLOCK           ; LBLOCK = next block to read
        TSTB    STOP                    ; did user enter control_c?
        BNEQ    695$                    ; yes - stop processing
        BRW     500$                    ; no - loop back for more
695$:
        SUBL3   #1,LBLOCK,CURBLK        ; compute last block searched
        TSTB    TAPFLG                  ; tape file?
        BNEQ    698$                    ; yes - skip
        CMPL    BUFFCT,#1               ; is buffer size set to one?
        BLEQ    698$                    ; yes - skip
        MOVL    CURBLK,PARA1            ; no - set up and read in
        BSBW    READ                    ;  the required block count
        BRW     970$                    ; exit
698$:
        BRW     900$                    ; exit to 900$ for tape or buff ct=1
;
;       "find" condition or user interrupt from global search
;
700$:
        TSTB    TAPFLG                  ; tape device?
        BNEQ    740$                    ; yes - skip this
        ADDL2   #512,NXTBCT             ; compute NXTBCT = remaining bytes
        SUBL2   R6,NXTBCT               ;  in current buff, incl found block
        MULL3   #512,BUFFCT,LSTBCT      ; LSTBCT = required bytes
        CMPL    NXTBCT,LSTBCT           ; do we have enough?
        BGEQ    720$                    ; yes - skip
        BLBS    SVSTAT,710$             ; continue if last read was good
        MOVL    NXTBCT,LSTBCT           ; otherwise, use reduced size
        BRB     720$
710$:
        MOVL    R10,PARA1               ; set up to read at found block
        PUSHL   LPTR                    ; save locate pointer
        BSBW    READ                    ; read required bytes from file
        MOVL    (SP)+,LPTR              ; restore locate pointer and exit
        BRW     970$
720$:
        MOVL    LSTBCT,CURBCT           ; set CURBCT for disk
740$:
        TSTL    R6                      ; R6 = buffer offset of block which
                                        ;  contains byte 1 of matched string
        BEQL    750$                    ; skip if zero
        MOVC3   LSTBCT,BUFF(R6),BUFF    ; move this block's data to BUFF
        MOVL    LSTBCT,CURBCT           ; update CURBCT
        CLRB    BSFLAG                  ; zero backspace flag
        INCB    FLAG                    ; set modified flag
750$:
        MOVL    R10,CURBLK              ; update CURBLK, R10 set by match rtn
        BRB     900$                    ; exit
800$:
        MOVL    CURBCT,LPTR             ; set locate pointer to "no find"
        TSTL    FNDCNT                  ; did we find anything? (global only)
        BNEQ    820$                    ; yes - so indicate
        OUTMSG  #NFMSGL,NFMSG           ; no - output "no find" message
        BRB     900$                    ;  and exit
820$:
        MOVL    #100,OUTDSC             ; set up for FAO
        $FAO_S  CTRSTR=FNDCTM,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-     ;
                P1=FNDCNT               ; edit "total matches" message
        OUTMSG  OUTDSC,OUT_BUFF         ; output as message
900$:
        TSTB    BSFLAG                  ; test backspace flag
        BEQL    950$                    ; skip if zero
        BSBW    BACKSPACE               ; otherwise move back one block/eof
950$:
        TSTB    FLAG                    ; test for original buffer contents
        BEQL    970$                    ; yes, skip
        MNEGL   #1,RECPTR               ; no, initialize record pointer
970$:
        TSTL    FNDCNT                  ; did we find anything?
        BEQL    980$
        MOVC3   CURNAM,CURNAM,LOCNAM    ; if so, update file for SHOW LOCATE
980$:
        RSB                             ; return for next command
        .PAGE
;
;       MATCHIT is called from LOCATE above to search BUFF as follows:
;
;               R7 = buffer address (absolute) at which to begin search
;               R8 = number of bytes to search
;               LSTRX = target string
;               LSTRL = length of target string
;
MATCHIT:
        MOVL    R7,R9                   ; init R9 = address to search
        MOVL    R8,R10                  ; init R10 = byte count
        TSTB    LOCSFL                  ; do we need to uppercase data?
        BNEQ    200$                    ; no - skip
        MOVAL   UCBUFF,R9               ; yes - init R9 to search UCBUFF
        MOVW    R8,DESC                 ;
        MOVL    R7,DESC+4               ;
        MOVW    R8,UDESC                ; set up for uppercase translation
        MOVAL   UCBUFF,UDESC+4          ;
        BSBW    UPCASE                  ; do the translation
        BLBS    R0,200$                 ;
        BSBW    ERROUT                  ; error - so indicate to user
        CLRL    R0                      ; set to return internal error
        BRW     900$                    ;  and return to LOCATE
200$:
        MATCHC  LSTRL,LSTRX,R10,(R9)    ; compare here
        TSTB    LOCSFL                  ; case-insensitive compare?
        BNEQ    300$                    ; no - skip
        SUBL2   #UCBUFF,R3              ; yes - adjust R3 to make it appear that
        ADDL2   R7,R3                   ;  we were searching BUFF, not UCBUFF
300$:
        TSTL    R0                      ; did we find what we were looking for?
        BEQL    320$                    ; yes!
        BRW     700$                    ; nope - return "no find"
320$:
        INCL    FNDCNT                  ; increment find ct for global search
        SUBL2   LSTRL,R3                ; R3 = address of first matched byte
        SUBL3   #BUFF,R3,R9             ; R9 = address relative to BUFF
        TSTB    TAPFLG                  ; tape file?
        BNEQ    330$                    ;  yes, skip divide
        DIVL3   CURBCT,R9,R10           ; R10 = block relative to BUFF block
        BRW     340$                    ;
330$:
        CLRL    R10                     ; zero block offset
        CMPL    R9,CURBCT               ; find first byte in 1st or 2nd block?
        BLSS    340$                    ; skip if in first block
        INCL    R10                     ; otherwise, use offset of one
340$:
        MULL3   CURBCT,R10,R6           ; R6 = byte offset from BUFF to data
        SUBL2   R6,R9                   ; R9 = byte offset within find block
        ADDL2   LBLOCK,R10              ; adding LBLOCK - 1 to R10 makes
        DECL    R10                     ;  R10 = absolute block address
        MOVL    #100,OUTDSC             ; set up for edit
        MOVAL   FNDMSG,DESC+4           ; address of decimal control string
        TSTB    HEXFLG                  ; is RADIX=HEX?
        BEQL    345$
        MOVAL   FNDMSGX,DESC+4          ; if so, use addr of hex ctl string
345$:
        $FAO_S  CTRSTR=@DESC+4,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-    ;
                P1=R10,P2=R9            ; edit "find at block.. byte.." message
        MOVL    R10,LOCBLK
        MOVL    R9,LOCBYT               ; save block and byte for SHOW LOCATE
        TSTB    LGFLAG                  ; is this a global search?
        BNEQ    350$                    ; yes - skip
        OUTMSG  OUTDSC,OUT_BUFF         ; no - output as a message
        BRB     400$                    ;  and return "find"
350$:
        OUTPUT  OUTDSC,OUT_BUFF         ; global - output as normal text
        TSTB    STOP                    ; user interrupt?
        BEQL    450$                    ; yes - continue, otherwise retn "find"
400$:
        ADDL3   #1,R9,LPTR              ; update pointer for next locate
        MOVL    #1,R1                   ; set to return "find"
        BRW     800$                    ; return to LOCATE
450$:
        ADDL3   #1,R3,R9                ; R9 = address of next byte to search
        SUBL3   R7,R9,R2                ; R2 = byte count already searched
        SUBL3   R2,R8,R10               ; R10 = remaining bytes to search
        CMPL    R10,LSTRL               ; compare with target string length
        BLSS    700$                    ; not enough - return "no find"
        TSTB    LOCSFL                  ; case-insensitive compare?
        BNEQ    500$                    ; no
        ADDL3   #UCBUFF,R2,R9           ; yes - set to search UCBUFF
500$:
        BRW     200$                    ; loop back to continue search
700$:
        CLRL    R1                      ; set to return "no find"
800$:
        MOVL    #1,R0                   ; set to return "normal status"
900$:
        RSB
;
;       UPCASE is called from LOCATE and MATCHIT to translate a character
;       string (DESC) to upper case (UDESC).
;
UPCASE:
        TSTB    EBCFLG                  ; is charset=ebcdic?
        BNEQ    100$                    ; yes - use internal table
        PUSHAL  DESC
        PUSHAL  UDESC
        CALLS   #2,G^STR$UPCASE         ; no - translate ASCII
        BRB     200$
100$:
        MOVTC   DESC,@DESC+4,#0,EBUTBL,UDESC,@UDESC+4  ; trans EBCDIC
        MOVL    #1,R0                   ; good status
200$:
        RSB
        .PAGE
        .SBTTL  HELP - Call system help procedure
HELP::
        INCB    HLPON                   ; set help flag for TERMIO
        PUSHAL  HELPIN                  ; input routine address
        PUSHAL  HELPFLG                 ; HLP$M_PROMPT
        PUSHAL  HELPLIB                 ; SYS$HELP:
        PUSHAL  DESC                    ; initial input
        PUSHAL  HELPWID                 ; 80 characters
        PUSHAL  HELPOUT                 ; output routine address
        CALLS   #6,G^LBR$OUTPUT_HELP    ; call system help routine
        BLBS    R0,900$
        BSBW    ERROUT
900$:
        RSB

HELPIN:
        .WORD   ^M<R2>
        MOVL    4(AP),R2
        CVTWL   (R2),-(SP)              ; input buffer length
        PUSHL   4(R2)                   ; input buffer address
        MOVL    8(AP),R2
        CVTWL   (R2),-(SP)              ; prompt character count
        PUSHL   4(R2)                   ; prompt buffer address
        CALLS   #4,TERMIO               ; call TERMIO to do the read
        CMPL    (AP),#3
        BLSS    200$
        MOVW    TSTATUS+2,@12(AP)       ; returned input character count
200$:
        MOVL    #SS$_NORMAL,R0          ; always return normal status
        RET

HELPOUT:
        .WORD   ^M<R2>
        MOVL    4(AP),R2
        CVTWL   (R2),-(SP)              ; output character count
        PUSHL   4(R2)                   ; output buffer address
        CALLS   #2,TERMIO               ; call TERMIO to do the output
        MOVL    #SS$_NORMAL,R0          ; return normal status
        RET
        .PAGE
        .SBTTL  SETCMD - Process various SET options
SETCMD::
        TSTL    R1                      ; R1=0 means call from GETFILE
        BEQL    100$                    ;  if zero, no SET POSITION here
        TSTB    POSFLG
        BEQL    100$
        BSBW    SETPOS                  ; SET POSITION if POSFLG set
100$:
        BITL    #^X1000,SETMASK
        BEQL    110$
        BSBW    LOGOFF                  ; SET NOLOG
110$:
        BITL    #^X1,SETMASK
        BEQL    120$
        BSBW    LOGON                   ; SET LOG
120$:
        BITL    #^X2,SETMASK
        BEQL    200$
        MOVB    #1,DSPFLG               ; SET DISPLAY
200$:
        BITL    #^X2000,SETMASK
        BEQL    220$
        CLRB    DSPFLG                  ; SET NODISPLAY
220$:
        BITL    #^X4,SETMASK
        BEQL    300$
        MOVB    #1,SGNFLG               ; SET SIGN
300$:
        BITL    #^X4000,SETMASK
        BEQL    320$
        CLRB    SGNFLG                  ; SET NOSIGN
320$:
        BITL    #^X8,SETMASK
        BEQL    400$
        MOVB    #1,HDRFLG               ; SET HEADER
400$:
        BITL    #^X8000,SETMASK
        BEQL    420$
        CLRB    HDRFLG                  ; SET NOHEADER
420$:
        BITL    #^X10,SETMASK
        BEQL    500$
        MOVB    #1,CASFLG               ; SET CASE
500$:
        BITL    #^X10000,SETMASK
        BEQL    520$
        CLRB    CASFLG                  ; SET NOCASE
        CLRL    LPTR                    ; zero LOCATE pointer for this also
520$:
        BITL    #^X20,SETMASK
        BEQL    540$
        MOVB    #1,HEXFLG               ; SET RADIX=HEX
540$:
        BITL    #^X20000,SETMASK
        BEQL    560$
        CLRB    HEXFLG                  ; SET RADIX=DECIMAL
560$:
        BITL    #^X40,SETMASK
        BEQL    570$
        MOVB    #1,EBCFLG               ; SET CHARSET=EBCDIC
570$:
        BITL    #^X40000,SETMASK
        BEQL    580$
        CLRB    EBCFLG                  ; SET CHARSET=ASCII
580$:
        BITL    #^X100,SETMASK
        BEQL    600$
        MOVB    #1,BUGFLG               ; SET SKIP=FAST
        MOVL    #50,SKPINC
        BRB     640$
600$:
        BITL    #^X200,SETMASK
        BEQL    620$
        MOVB    #1,BUGFLG               ; SET SKIP=SLOW
        MOVL    #1,SKPINC
        BRB     640$
620$:
        BITL    #^X400,SETMASK
        BEQL    640$
        CLRB    BUGFLG                  ; SET SKIP=NORMAL
        MOVL    #50,SKPINC
640$:
        BITL    #^X800,SETMASK
        BEQL    660$
        MOVL    #1,R1                   ; indicate call from SET
        BSBW    SETWID                  ; SET WIDTH
        BLBS    R0,660$
        BSBW    ERROUT                  ; display error if necessary
660$:
        BITL    #^X100000,SETMASK       ; SET BUFF
        BEQL    680$
        TSTL    NBUFCT                  ; user-supplied buffer count
        BLEQ    670$                    ; error if < 1
        CMPL    NBUFCT,#LOCSIZ
        BGTR    670$                    ; error if > LOCSIZ
        MOVL    NBUFCT,BUFFCT           ; move into BUFFCT (now set)
        TSTB    TAPFLG
        BNEQ    680$                    ; skip if editing tape
        MULL3   #512,BUFFCT,R1          ; max new buffer size
        CMPL    R1,CURBCT               ; is current buffer within this range?
        BGEQ    680$                    ;  yes, skip
        MOVL    R1,CURBCT               ;  no, reduce to new max size
        BRB     680$
670$:
        OUTMSGC INVBCT                  ; if error, indicate to user
680$:
        RSB
        .PAGE
        .SBTTL  SHOCMD - Process the SHOW command
SHOCMD::
        CLRB    CHAR1                   ; line feed char = null
        BITL    #^X10,SHOMASK
        BEQL    50$
        BSBW    SHOFILE                 ; SHOW FILE
        MOVB    #LF,CHAR1               ; set for line feed now
50$:
        BITL    #^X1,SHOMASK            ; test for SHOW MODES
        BNEQ    100$
        BRW     200$
100$:
        OUTMSGC MODMSG                  ; "current mode settings:"
        MOVL    #20,OUTDSC
        $FAO_S  CTRSTR=BUFMOD,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=BUFFCT
        OUTMSG  OUTDSC,OUT_BUFF         ; BUFF=count
        MOVB    CASFLG,R1
        MOVAL   CASMOD,R2
        BSBW    MODOUT1                 ; CASE setting
        MOVAL   CHRMOD,R2
        MOVAL   CHRASC,R7
        TSTB    EBCFLG
        BEQL    110$
        MOVAL   CHREBC,R7
110$:
        BSBW    MODOUT2                 ; CHARSET setting
        MOVB    DSPFLG,R1
        MOVAL   DSPMOD,R2
        BSBW    MODOUT1                 ; DISPLAY setting
        MOVB    HDRFLG,R1
        MOVAL   HDRMOD,R2
        BSBW    MODOUT1                 ; HEADER setting
        BSBW    SHOLOG                  ; LOG setting
        MOVAL   RADMOD,R2
        MOVAL   RADDEC,R7
        TSTB    HEXFLG
        BEQL    130$
        MOVAL   RADHEX,R7
130$:
        BSBW    MODOUT2                 ; RADIX setting
        MOVB    SGNFLG,R1
        MOVAL   SGNMOD,R2
        BSBW    MODOUT1                 ; SIGN setting
        MOVAL   SKPMOD,R2
        MOVAL   SKPNRM,R7
        TSTB    BUGFLG
        BEQL    150$
        MOVAL   SKPFST,R7
        CMPL    SKPINC,#1
        BGTR    150$
        MOVAL   SKPSLW,R7
150$:
        BSBW    MODOUT2                 ; SKIP setting
        MOVL    #20,OUTDSC
        $FAO_S  CTRSTR=WIDMOD,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=TERMWD
        OUTMSG  OUTDSC,OUT_BUFF         ; WIDTH=count
        MOVB    #LF,CHAR1               ; set to LF now
200$:
        BITL    #^X2,SHOMASK
        BEQL    300$
        MOVAL   CHGMOD,R7
        MOVAL   CHGPAR,R8
        BSBW    SHOSTR                  ; SHOW CHANGE
300$:
        BITL    #^X4,SHOMASK
        BEQL    400$
        MOVAL   LOCMOD,R7
        MOVAL   LOCPAR,R8
        BSBW    SHOSTR                  ; SHOW LOCATE
400$:
        BITL    #^X8,SHOMASK
        BEQL    500$
        MOVL    #50,OUTDSC
        $FAO_S  CTRSTR=PBMOD,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=PBBCT
        MOVB    CHAR1,OUT_BUFF
        OUTMSG  OUTDSC,OUT_BUFF         ; SHOW PASTE first line
        TSTL    PBBCT
        BEQL    500$                    ; skip if paste buffer empty
        MOVAL   CUTMSG,R6
        MOVAL   PSTPAR,R8
        BSBW    SHOPOS                  ; SHOW PASTE second line
500$:
        RSB
;
;       MODOUT1 is called for on/off modes, such as CASE, DISPLAY.
;          at entry, R2 is address of counted string literal for mode
;                    R1=0, add "NO" to display output
;
MODOUT1:
        MOVAL   OUT_BUFF+8,R6           ; first 8 chars are blanks
        TSTB    R1
        BNEQ    100$
        MOVW    #^A/NO/,(R6)+           ; move in "NO" if R1 = 0
100$:
        MOVZBL  (R2),R1                 ; string length
        MOVC3   R1,1(R2),(R6)           ; move into buffer
        SUBL2   #OUT_BUFF,R3
        OUTMSG  R3,OUT_BUFF             ; output message
        RSB
;
;       MODOUT2 is called for typed modes, such as CHARSET, RADIX.
;          at entry, R2 is address of counted string literal for mode
;                    R7 is address of counted string literal for setting
MODOUT2:
        MOVZBL  (R2),R1                 ; mode string length
        MOVC3   R1,1(R2),OUT_BUFF+8     ; move into buffer+8
        MOVZBL  (R7),R1                 ; setting type string length
        MOVC3   R1,1(R7),(R3)           ; append into buffer
        SUBL2   #OUT_BUFF,R3
        OUTMSG  R3,OUT_BUFF             ; output message
        RSB
;
;       SHOSTR is called for SHOW CHANGE and SHOW LOCATE.
;          at entry, R7 is address of 6-char literal "CHANGE" or "LOCATE"
;                    R8 is address of parameter block for change or locate
;
SHOSTR:
        TSTL    (R8)                    ; test length of chg/loc string
        BGTR    100$                    ; skip if greater than zero
        MOVB    CHAR1,NOSTR+1           ; null or LF
        MOVC3   #6,(R7),NOSTR+22        ; move in "CHANGE" or "LOCATE"
        OUTMSGC NOSTR                   ; "there is no xxxxxxx string"
        BRW     900$                    ; exit
100$:
        MOVC3   #STMLEN,STRMSG,OUT_BUFF ; move in "current xxxxxx string="
        MOVC3   #6,(R7),OUT_BUFF+9      ; repl xxx with "CHANGE" or "LOCATE"
        MOVAL   OUT_BUFF+STMLEN,R6      ; R6 is next address in output buffer
        TSTB    4(R8)                   ; test for character string (type 0)
        BNEQ    150$                    ; skip if not
;
;       insert character string into message
;
        MOVB    #^A/"/,(R6)+            ; char string - insert leading quote
        MOVC3   (R8),@8(R8),(R6)        ; move string into buffer
        ADDL2   (R8),R6                 ; update address
        MOVB    #^A/"/,(R6)+            ; insert trailing quote
        MOVC3   #STCLEN,STRCHS,(R6)     ; move in "(character string)"
        ADDL2   #STCLEN,R6              ; update address
        BRW     300$                    ; go output message
150$:
        CMPB    4(R8),#2                ; test type for decimal (1 or 2)
        BLEQ    160$
        BRW     250$                    ; skip if not
;
;       insert decimal number into message
;
160$:
        MOVAL   STRDECB,R5              ; R5 is FAO control str descr address
        CVTBL   @8(R8),R9               ; R9 is value
        CMPB    (R8),#1
        BLEQ    180$                    ; length 1 is a byte
        MOVAL   STRDECW,R5
        CVTWL   @8(R8),R9
        CMPB    (R8),#2
        BLEQ    180$                    ; length 2 is a word
        MOVAL   STRDECL,R5
        MOVL    @8(R8),R9               ; otherwise, longword
180$:
        MOVL    4(R5),R2                ; address of FAO control string
        MOVB    #^A/+/,(R2)             ; indicate positive constant
        CMPB    4(R8),#1                ; test for neg constant
        BLEQ    200$
        MOVB    #^A/-/,(R2)             ; if neg, use minus sign
        MNEGL   R9,R9                   ;  and negate number for FAO
200$:
        MOVL    R5,SHOPTR               ; save ctrl string address
        MOVW    #50,DESC
        MOVL    R6,DESC+4               ; set up to append to existing msg
        $FAO_S  CTRSTR=@SHOPTR,OUTLEN=DESC,OUTBUF=DESC,-
                P1=R9
        CVTWL   DESC,R1
        ADDL2   R1,R6                   ; add FAO output len to R6
        BRW     300$                    ; go output message
;
;       insert hex string into message
;
250$:
        MOVL    8(R8),R4                ; address of start of data
        MOVL    (R8),R5                 ; length of hex string
260$:
        EXTZV   #4,#4,(R4),R9
        MOVB    HEXD[R9],(R6)+          ; append first hex char
        EXTZV   #0,#4,(R4)+,R9
        MOVB    HEXD[R9],(R6)+          ; append second hex char
        SOBGTR  R5,260$                 ; loop back for remaining bytes
        MOVC3   #STHLEN,STRHEX,(R6)     ; append "(hex string)"
        ADDL2   #STHLEN,R6
;
;       output message
;
300$:
        MOVB    CHAR1,OUT_BUFF          ; move in null/LF
        SUBL2   #OUT_BUFF,R6            ; compute char count
        OUTMSG  R6,OUT_BUFF             ; output here
        TSTW    @20(R8)                 ; check if file spec present
        BEQL    900$                    ; skip if not
        MOVL    LSTMSG+4,R1             ; address of "Last xxxxxxd at"...
        MOVC3   #6,(R7),5(R1)           ; move in CHANGE/LOCATE
        MOVAL   LSTMSG,R6               ; R6 = descriptor for above
        BSBW    SHOPOS                  ; go output second line
900$:
        MOVB    #LF,CHAR1               ; set for LF between messages
        RSB
;
;       SHOPOS is called for SHOW CHANGE, LOCATE, PASTE, to format and
;       output the second line of the message when appropriate.
;          at entry, R6 = descriptor for first part of second line message
;                    R8 = parameter block address
;
SHOPOS:
        MOVAL   FILMOD,SHOPTR           ; control string with dec byte ind
        TSTB    HEXFLG
        BEQL    100$
        MOVAL   FILMODX,SHOPTR          ; if RAD=HEX, use hex byte ind
100$:
        MOVL    20(R8),R2               ; address of file name info
        SUBW3   #2,(R2),DESC            ; byte count of file name
        ADDL3   #2,R2,DESC+4            ; address of file name string
        MOVL    #150,OUTDSC
        $FAO_S  CTRSTR=@SHOPTR,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=R6,P2=12(R8),P3=16(R8),P4=#DESC
        OUTMSG  OUTDSC,OUT_BUFF         ; output second line and exit
        RSB
;
;
;
        .SBTTL  ADD - Add 1 or more numbers & print
ADD::
        MOVAL   ADDMSG,R1               ; signed output control string
        TSTB    SGNFLG
        BNEQ    100$
        MOVAL   ADDMSGU,R1              ; use unsigned if SET NOSIGN
100$:
        MOVL    #30,OUTDSC
        $FAO_S  CTRSTR=(R1),OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=ACCUM,P2=ACCUM
        OUTMSG  OUTDSC,OUT_BUFF         ; output total line
        RSB
        .PAGE
        .SBTTL  Miscellaneous utility routines

ERROUT::
        MOVL    #80,OUTDSC
        $GETMSG_S  MSGID=R0,MSGLEN=OUTDSC,BUFADR=OUTDSC
        OUTMSG  OUTDSC,OUT_BUFF
        RSB

ZEROBLK::
        MOVL    #1,R0
        TSTL    CURBCT
        BGTR    200$
        MOVL    PARA1,P1SAVE
        MOVL    #1,PARA1
        BSBW    NEXT
        BLBC    R0,100$
        BSBW    BLOCK
100$:
        MOVL    P1SAVE,PARA1
200$:
        RSB

BLOCK::
        MOVL    #20,OUTDSC
        $FAO_S  CTRSTR=BLKMSG,OUTLEN=OUTDSC,OUTBUF=OUTDSC,-
                P1=CURBLK
        OUTPUT  OUTDSC,OUT_BUFF
        RSB

INVPARA::
        OUTMSG  #INVPL,INVP
        MOVL    #0,R0
        RSB

EXIT::
        BSBW    LOGOFF
        BSBW    RELFILE
        MOVL    #1,R0
ERREXT::
        MOVL    R0,SVSTAT
        MOVL    INITWID,NEWWID
        CLRL    R1
        BSBW    SETWID
        $EXIT_S CODE=SVSTAT
        .PAGE
        .SBTTL  Data definitions

        .PSECT  DATA,WRT,NOEXE,LONG

DESC::  .WORD   80
        .WORD   ^X010E
        .ADDRESS  FNAME

OUTDSC:: .LONG  200
        .ADDRESS  OUT_BUFF
OUT_BUFF:: .BLKB  200

SIGNON: .ASCII  /MCCCD VFE V2.0 /
SIGN2:  .ASCII  /dd-mmm-yyyy hh:mm:ss.cc/
SGNL=.-SIGNON-6
SGNTIM: .WORD   23
        .WORD   ^X010E
        .ADDRESS SIGN2

INVP:   .ASCII  /Invalid parameter(s)/
INVPL=.-INVP

CBEMPTY:: .ASCIC /The current buffer is empty./

PBEMPTY:: .ASCIC /The paste buffer is empty./

PBSMALL: .ASCID /Paste buffer contains !UL bytes - remaining !UL bytes zeroed./

PBLARGE: .ASCID /Paste buffer contains !UL bytes - only !UL bytes transferred./

NFMSG:  .ASCII  /Not found./
NFMSGL=.-NFMSG

BLKMSG: .ASCID  /Block !SL/

FNDMSG: .ASCID  /Find at block !SL, byte !UL/
FNDMSGX: .ASCID /Find at block !SL, byte !4XL/

FNDCTM: .ASCID  /Total matches: !UL/

INVBCT: .ASCIC  /Invalid buffer count/

MODMSG: .ASCIC  / Current mode settings:/
CHAR1=MODMSG+1
BUFMOD: .ASCID  /        BUFF=!UL/
CASMOD: .ASCIC  /CASE/
CHRMOD: .ASCIC  /CHARSET=/
CHRASC: .ASCIC  /ASCII/
CHREBC: .ASCIC  /EBCDIC/
DSPMOD: .ASCIC  /DISPLAY/
HDRMOD: .ASCIC  /HEADER/
RADMOD: .ASCIC  /RADIX=/
RADDEC: .ASCIC  /DECIMAL/
RADHEX: .ASCIC  /HEX/
SGNMOD: .ASCIC  /SIGN/
SKPMOD: .ASCIC  /SKIP=/
SKPNRM: .ASCIC  /NORMAL/
SKPFST: .ASCIC  /FAST/
SKPSLW: .ASCIC  /SLOW/
WIDMOD: .ASCID  /        WIDTH=!UL/
CHGMOD: .ASCII  /change/
LOCMOD: .ASCII  /locate/
PBMOD:  .ASCID  / The paste buffer contains !UL bytes./
NOSTR:  .ASCIC  / There is no current xxxxxx string./
STRMSG: .ASCII  / Current xxxxxx string = /
STMLEN=.-STRMSG
STRCHS: .ASCII  / (character string)/
STCLEN=.-STRCHS
STRDECB: .ASCID /x!3ZB (decimal byte)/
STRDECW: .ASCID /x!5ZW (decimal word)/
STRDECL: .ASCID /x!10ZL (decimal longword)/
STRHEX: .ASCII  / (hex string)/
STHLEN=.-STRHEX
LSTMSG: .ASCID  /Last xxxxxxd at/
CUTMSG: .ASCID  /Cut from/
FILMOD: .ASCID  /!AS block !SL byte !UL of !AS/
FILMODX: .ASCID /!AS block !SL byte !4XL of !AS/

ADDMSG: .ASCID  /!SL(10)  !XL(16)/
ADDMSGU: .ASCID /!UL(10)  !XL(16)/

HELPLIB: .ASCID /SYS$HELP:VFE.HLB/
HELPFLG: .LONG  HLP$M_PROMPT
HELPWID: .LONG  80
HLPON:: .BYTE   0

EBUTBL:
        .BYTE     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15
        .BYTE    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
        .BYTE    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
        .BYTE    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
        .BYTE    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79
        .BYTE    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
        .BYTE    96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111
        .BYTE   112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127
        .BYTE   128,193,194,195,196,197,198,199,200,201,138,139,140,141,142,143
        .BYTE   144,209,210,211,212,213,214,215,216,217,154,155,156,157,158,159
        .BYTE   160,161,226,227,228,229,230,231,232,233,170,171,172,173,174,175
        .BYTE   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191
        .BYTE   192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
        .BYTE   208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
        .BYTE   224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239
        .BYTE   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255

INITWID: .LONG  0

TERMON::
DSPFLG: .BYTE   1
NOLOG:: .BYTE   1

SGNFLG:: .BYTE  1

HDRFLG:: .BYTE  1

CASFLG:: .BYTE  1

HEXFLG:: .BYTE  0

EBCFLG:: .BYTE  0

STOP::  .BYTE   0

ACCUM:: .LONG   0

P1SAVE: .LONG   0
SVSTAT: .LONG   0
FLAG:   .BYTE   0
BSFLAG: .BYTE   0
LSTBCT: .LONG   0
FNDCNT: .LONG   0
LGFLAG:: .BYTE  0
LOCSFL: .BYTE   0
LBLOCK: .LONG   0
LBLKCT: .LONG   0
REMCT:  .LONG   0
SHOPTR: .LONG   0

PSTPAR:
PBBCT:: .LONG   0
        .LONG   0
        .ADDRESS  PBUFF
PSTBLK: .LONG   0
PBOFF:: .LONG   0
        .ADDRESS  PSTNAM
PSTNAM: .WORD   0
        .BLKB   200

CHGPAR:
CSTRL:: .LONG   0
CSTRT:: .LONG   0
        .ADDRESS  CSTR
CHGBLK: .LONG   0
CHGBYT: .LONG   0
        .ADDRESS  CHGNAM
CSTR::  .BLKB   100
CHGNAM: .WORD   0
        .BLKB   200

LOCPAR:
LSTRL:: .LONG   0
LSTRT:: .LONG   0
        .ADDRESS  LSTR
LOCBLK: .LONG   0
LOCBYT: .LONG   0
        .ADDRESS  LOCNAM
LPTR::  .LONG   0
LSTR::  .BLKB   100
LSTRX:  .BLKB   100
LOCNAM: .WORD   0
        .BLKB   200

UDESC:  .QUAD   0
SAVBCT: .LONG   0
SBUFF:  .BLKB   LOCSIZ*512

        .ALIGN  LONG
BUFF::  .BLKB   MAXBCT*2
PBUFF:: .BLKB   MAXBCT
UCBUFF: .BLKB   MAXBCT+200

        .END    START
$*$*EOD*$*$
$ checksum VFE.MAR
$ if checksum$checksum .ne. check_sum then -
$   write sys$output "Checksum failed, file probably corrupted"
$ exit

charettep%v36b.DECnet@NUSC.ARPA ("V36B::CHARETTEP") (07/28/87)

	The Virtual File Editor looks interesting, but I only received parts
1 thru 4.  Could someone out there in netland forward me part 5?

							Thanks in advance,

							Paul Charette

              "I'm having amnesia and deja vu at the same time"

          +--------------------------------------------------------+
          |                     Paul Charette                      |
          |            Naval Underwater Systems Centre             |
          |                      Newport, RI                       |
          |                                                        |
          |           <charettep%v36b.decnet@nusc.ARPA>            |
          +--------------------------------------------------------+

------

edwards@uwmacc.UUCP (mark edwards) (07/30/87)

In article <8707291433.AA21379@ucbvax.Berkeley.EDU> "V36B::CHARETTEP" <charettep%v36b.decnet@nusc.arpa> writes:
:
:	The Virtual File Editor looks interesting, but I only received parts
:1 thru 4.  Could someone out there in netland forward me part 5?
:
:							Thanks in advance,

  Me too. It must have got munged somewhere.

  mark
-- 
    edwards@vms.macc.wisc.edu
    {allegra, ihnp4, seismo}!uwvax!uwmacc!edwards
    UW-Madison, 1210 West Dayton St., Madison WI 53706

TRIN7@TRINCC.BITNET (07/30/87)

hello all,

A few days ago, a program called the Virtual File Editor was posted in parts
over the net.  I am very much interested in this program.  However, I only
received parts 1 through 4. Could someone please forward me part 5.
        thanks, Scott.

Bitnet: trin7@trincc
------