* I/O Op Code 0 - OPEN
*
* This module will check the attributes of the file to open,
* make sure everything's OK and open the file.  A maximum of
* 16 files can be open at one time.  If a user attempts to
* open a 17th file, an error is returned
*
* Date: April 21, 1995 (One week before Lima!)
*
* Author: David Nieters
*


* We will begin by making sure the file isn't open already

OPEN0
       ANDI R12,>FF00
       AI   R12,24

       LDCR @B02,4            Select RAM bank 2
       BLWP @IFO
       JNE  OPEN1

       BL   @DSRERR           File is already open / Error!
       DATA >0200             Bad open attribute

* Make sure that there are not too many files open already
OPEN1
       LDCR @B02,4           Select RAM bank 2
       LI   R1,OFCASH
OPEN1A C    @4(R1),@ZERO
       JEQ  OPEN2
       AI   R1,100
       CI   R1,>6000
       JL   OPEN1A
       BL   @DSRERR          There are too many files open!
       DATA >0400            Out of space error

* If the file is being opened in relative mode, assume
* the record format is fixed.
OPEN2  LDCR @ZERO,4
       MOVB @PABBUF+1,R1
       ANDI R1,>0100
       JEQ  OPEN3
       MOVB @PABBUF+1,R1
       ANDI R1,>EFFF
       MOVB R1,@PABBUF+1

* See how the file is to be opened and branch to the
* right piece of code.

OPEN3
       MOV  @PABBUF,R1
       ANDI R1,>0006          Mask out the mode of operation
       MOV  @OPENJT(R1),R2    Get address of open routine
       B    *R2

* This jump table gives the entry point for each of the 4
* modes a file can be open

OPENJT DATA OPENUP            Update mode
       DATA OPENOU            Output mode
       DATA OPENIN            Input mode
       DATA OPENAP            Append Mode


* Here are some subroutines used by OPEN
*

**
*
*  OSCASH - OPEN SETUP CACHE
*
*  This procedure allocates a cache entry and fills in
*  the following fields -
*
*  SCSI ID, Name Length, FDR bank, Buffer Bank, FDR Address,
*  Buffer Address, Full file name, AU of FDR, File Open Attributes
*
*  It resets all other fields to zero.
*
**

OSCASH
       LDCR @B02,4            Select RAM bank 2
       LI   R4,OFCASH
       LI   R3,>5000          FDR pointer
OSC1   C    @4(R4),@ZERO      Is this cache entry used?
       JEQ  OSC2              If not, we will use it

       AI   R3,>100           Otherwise, check next one
       AI   R4,100
       JMP  OSC1
OSC2

* Now fill in the cache entry
*
       MOVB R6,*R4            SCSI ID
       MOVB @B05,@2(R4)       FDR bank
       MOV  R3,@4(R4)         FDR address
       MOV  R3,R1             Compute bank of buffer (6 or 7)
       ANDI R1,>0800
       SRL  R1,3
       AI   R1,>0600
       MOVB R1,@3(R4)         Buffer Bank
       ANDI R3,>0700          Compute buffer address
       SLA  R3,1
       AI   R3,>5000
       MOV  R3,@6(R4)         Buffer address

* Now move the file name to the cache entry.  While we are
* moving it, we will compute the file name's length.  While
* the length isn't used now, in a future version of the
* DSR, it can use the length to quickly search through the
* cache entries to find the right match

       CLR  R1                R1 will compute file name length
       AI   R4,8
       LI   R3,NCB
       LI   R0,40
OSC3   CB   @SPACE,*R3
       JEQ  OSC4
       INC  R1                Increment file name length
OSC4   MOVB *R3+,*R4+
       DEC  R0
       JNE  OSC3

       SWPB R1                Now put in the file name length
       MOVB R1,@-47(R4)

       LDCR @B04,4            Select RAM bank 4
       MOV  @SAVEAU,R0        Get AU of the FDR
       LDCR @B02,4            Select RAM bank 2
       MOV  R0,*R4+           Store the FDR's AU

       CLR  *R4+              Current AU (none)
       CLR  *R4+              Sector within AU
       CLR  *R4+              Pointer within buffer

* Get the file open attribute from the PAB

       LDCR @ZERO,4
       MOVB @PABBUF+1,R1
       ANDI R1,>0600
       SRL  R1,1
       LDCR @B02,4
       MOVB R1,*R4+

* Now see if it is sequential or relative

       LDCR @ZERO,4
       MOVB @PABBUF+1,R1
       ANDI R1,>0100
       LDCR @B02,4
       MOVB R1,*R4+

       CLR  *R4+              Buffer size
       CLR  *R4+              Buffer Modified
       CLR  *R4+              Sector or Record #

       AI   R4,-64            Reset pointer
       RT

       PAGE
