;***************************************************************************;
;                                                                           ;
;                                   OPEN                                    ;
;                     Displays open files on the system                     ;
;                                                                           ;
;***************************************************************************;
;Copyright (C) 1988 UltraSoft Corporation.  All Rights Reserved.
;
;Written by: David Pallmann
;
;Edit History:
;2.0(100)  complete rewrite (works much, much better). /DFP
;
;Assembly Notes:
;
;       OPEN requires no special files, other than those that are normally
;       distributed with AMOS.  You DO have to link OPEN after assembly,
;       however:
;
;                       Step 1:         .M68 OPEN
;                       Step 2:         .LNKLIT OPEN
;
;How OPEN works:
;
;       Regrettably, AMOS doesn't keep track of which files are open
;       (unless you're running LOKSER).  OPEN finds open files anyhow
;       by using the following brute-force technique:  The memory
;       partition for each job is scanned for what looks like a file
;       DDB.  If enough fields in the alleged-DDB check out, OPEN assumes
;       it has a bonafide open file, and outputs information about it.
;
;       This is the only way to hunt out open files currently; if OPEN has
;       to scan a job with a particularly large memory partition, you may
;       notice some delays.  Again, this can't be helped.
;
;       This version of OPEN is much more effective than the previous
;       version, which assumed that I/O buffers for files were always
;       separate memory modules.  This is not the case in AlphaWRITE,
;       AlphaBASIC, and many other applications.  The new OPEN properly
;       identifies ALL open files to the best of our knowledge.
;
;       The following is the current definition for what OPEN considers
;       an open file:
;
;               A region of memory is considered a DDB if:
;
;                       1. The area of memory is in a job's partition.
;                       2. The longword D.DDB(address) contains 512.
;                       3. The byte D.OPN(address) contains 1, 2, 4, or 8.
;                       4. The longword D.BUF(address) is an address that
;                          resides in the same user partition as the DDB.
;
;       This definition should suffice for just about all files opened
;       under AMOS.

;********************
;*  version number  *
;********************

       VMAJOR=2
       VMINOR=0
       VSUB=0
       VEDIT=100.
       VWHO=0

;***************
;*  externals  *
;***************

       ASMMSG  "After assembly, enter:  .LNKLIT OPEN"
       EXTERN  $ODTIM

;****************
;*  universals  *
;****************

       SEARCH  SYS
       SEARCH  SYSSYM

;************************************
;*  register usage throughout OPEN  *
;************************************
;
;       D0 - unused                     A0 - index into job table (JOBTBL)
;       D1 - used for OCVT calls        A1 - buffer address
;       D2 - unused                     A2 - current index into job memory
;       D3 - used for $ODTIM call       A3 - end of job memory
;       D4 - used for $ODTIM call       A4 - JCB address of current job
;       D5 - used for $ODTIM call       A5 - unused

;************
;*  macros  *
;************

DEFINE  OUTNAM  ADDR
       SAVE    A1-A2
       SUB     #8.,SP
       LEA     A1,ADDR
       MOV     SP,A2
       UNPACK
       UNPACK
       CLRB    @A2
       TTYL    @SP
       ADD     #8.,SP
       REST    A1-A2
       ENDM

;********************
;*  program header  *
;********************

START:  PHDR    -1,,PH$REE!PH$REU       ; reentrant & reusable (as always)

;******************************************
;*  clear screen and print column titles  *
;******************************************

HEADER: MOVW    #<-1_8.>,D1             ; clear
       TCRT                            ;  screen
       TYPESP  Open Files as of
       CLR     D3
       CLR     D4
       MOV     #-1,D5
       MOV     #0,A2
       CALL    $ODTIM
       CRLF
       CRLF
       TYPECR  Job     Term    Prog    DDB Address  Access  File
       TYPECR  ------  ------  ------  -----------  ------  --------------------------

;***************************
;*  loop to scan all jobs  *
;***************************

ALLJOB: MOV     JOBTBL,A0               ; point to job table
10$:    CTRLC   20$                     ; branch on control-C
       MOV     (A0)+,D7                ; get JCB address
       BEQ     10$                     ; deallocated job - skip
       BMI     20$                     ; end of job table - all done
       MOV     D7,A4                   ; put JCB in A4 for subroutines
       CALL    SCAN                    ; scan the job @A4 for open files
       BR      10$                     ; proceed to the next job
20$:    CRLF                            ; we're done, print a blank line
       EXIT                            ; exit to AMOS

;*************************************
;*  scan the job @A4 for open files  *
;*************************************

SCAN:   TST     JOBSIZ(A4)              ; does this job have any memory?
       JEQ     SCNRTN                  ;  no
       MOV     JOBBAS(A4),A2           ; A2 := base of job's memory
       MOV     A2,A3                   ; copy base
SCNWLK: TST     @A3                     ; end of job's memory map?
       BEQ     SCNDDB                  ;  yes
       ADD     @A3,A3                  ;  no - skip next module
       BR      SCNWLK                  ;       and loop
SCNDDB: CMP     A2,A3                   ; end of partition?
       JHIS    SCNRTN                  ;  yes - we are done w/this job
       CMP     D.SIZ(A2),#512.         ; is this a DDB - rec size 512?
       BNE     SCNNXT                  ;  no, this isn't a DDB
       MOV     D.BUF(A2),A1            ; get buffer address
       CMM     A1,JOBBAS(A4)           ; is buffer address in user memory?
       BLO     SCNNXT                  ;  no (too low) - can't be a DDB
       CMP     A1,A3                   ; is buffer address in user memory?
       BHIS    SCNNXT                  ;  no (too high) - can't be a DDB
       MOVB    D.OPN(A2),D4            ; get OPEN code
       CMPB    D4,#1                   ; open for input?
       BEQ     SCNFIL                  ;  yes - valid DDB
       CMPB    D4,#2                   ; open for output?
       BEQ     SCNFIL                  ;  yes - valid DDB
       CMPB    D4,#4                   ; open for random I/O?
       BEQ     SCNFIL                  ;  yes - valid DDB
       CMPB    D4,#10                  ; open for appending?
       BNE     SCNNXT                  ;  no - not avalid DDB
SCNFIL: CALL    DISPLAY                 ; output the DDB we found
SCNNXT: CTRLC   SCNRTN
       ADD     #2,A2
       BR      SCNDDB
SCNRTN: RTN

;*************************************************************************
;*  display line - DDB address is @A2, JCB address @A4, open code in D4  *
;*************************************************************************

DISPLAY:
       OUTNAM  JOBNAM(A4)              ; *** output job name
       TYPE    <  >
       MOV     JOBTRM(A4),A6           ; *** output terminal name
       OUTNAM  -4(A6)
       TYPE    <  >
       OUTNAM  JOBPRG(A4)              ; *** output program name
       TYPE    <  >
       MOV     A2,D1                   ; *** output DDB addr
       OCVT    13,OT$TRM!OT$ZER
       TYPE    <  >
       CMPB    D4,#1                   ; *** output file access
       BEQ     10$
       CMPB    D4,#2
       BEQ     20$
       CMPB    D4,#4
       BEQ     30$
       TYPE    <append>
       BR      40$
10$:    TYPE    <input >
       BR      40$
20$:    TYPE    <output>
       BR      40$
30$:    TYPE    <random>
40$:    TYPE    <  >
       PFILE   @A2                     ; *** output filename
       CRLF
       RTN

       ASCIZ   /Copyright (C) 1988 UltraSoft Corp.  All Rights Reserved./
       EVEN

       END