! Formats for shared memory.  These are required for two reasons:
!     1) There is no point in making the object modules extra
!        large by having, for example, the system buffers written
!        in as %own.
!     2) There is a limit of 32K on the %own/%external area.


! Monitor block.  Record statistics on the filestore usage.

%constinteger last stat = 11
%recordformat monitor fm((%integer file reads,
                          %integer file writes,
                          %integer dir reads,
                          %integer dir writes,
                          %integer disc errors,
                          %integer ether reads,
                          %integer ether writes,
                          %integer ether errors,
                          %integer OK ops,
                          %integer error ops,
                          %integer logons) %c
                     %or %integerarray s(1 : last stat))


! Trace buffer.  This holds a circular list of all the filestore requests
! and replies, for use in debugging clients.  Each trace record holds
! the ether context of the request/reply, the direction of the message
! and the text of the message.  The contents of any data parts are not
! stored.  Note that commands involving passwords have any sensitive
! information zapped before being put into the trace buffer.  Two
! pointers to the current position are required in order that the boundaries
! of the valid trace information can be determined by the Trace program,
! since the act of reading the trace buffer necessarily requires that the
! pointers be moved.

%recordformat trace fm(%integer context, inout,
                       %string(55) text)
%recordformat trace buffer fm(%integer q,
                              %record(trace fm)%array t(0 : tbuffs),
                              %integer p)
%constinteger trace in  = 0
%constinteger trace out = 1


! Timestamp record, used to record the dates and times when Unos, Xnos
! and ports have last been used.

%recordformat stamp fm(%short date, time)


! Ether port information

%recordformat port fm(%integer remote, port, state, buffer,
                      %integer retries, NAK last, count,
                      %record(stamp fm) opened stamp, active stamp)
! <remote> is address of client talking to our port
! <port> is the remote port which the client is using
! <state> gives info on the port's current activity
! <buffer> is address of a buffer waiting to be sent
! <NAK last> indicates whether last packet sent got there
! <opened stamp> indicates when the port was opened
! <active stamp> indicates when outgoing data was last written


! Ether receive buffers

%recordformat ether buffer fm(%integer context,
                              %integer bytes,
                              %bytearray data(0 : ether packet size))
! <context>  >= 0 for port number -- forward to a user process
!            <  0 for non-standard processing by ether process
! <bytes> indicates how much of <data> has been used

%recordformat ether buffer area fm(%integer next to use,
                                   %integer next to process,
                                   %record(ether buffer fm)%array %c
                                                buffer(0 : ether buffers))
! <next to use> gives next buffer to be written by ether packet receiver
! <next to process> gives next buffer to be processed by ether RX process


! Data buffer, containing filestore request split apart into its constituent
! parts for convenience.

%recordformat buffer fm(%integer       link,
                        %integer       context,
                        %integer       ether packet,
                        %integer       ether bytes,
                        %integer       sync,
                        %integer       error,
                        %integer       bytes,
                        %string(255)   text,
                        %bytearray     b(0 : 511),
                        %string(31)    guard)
! <link> chains buffer on a request queue or the free list
! <context> gives ether context of request
! <ether packet> is buffer number of incoming request (diagnostic)
! <sync> is used to synchronise multi-packet responses ('Z')
! <error> contains 0 (for success) or a filestore error number
! <b> contains the data part of a request, with <bytes> indicating
!     how much of it is used.
! <text> contains filestore command/response text


! Partition information block, one for each partition.

%recordformat register fm (%integerarray owner(1 : u per p))
%recordformat bitmap fm   (%bytearray b(0 : bitmap size))

%recordformat partition fm(%record(register fm) register,
                           %record(bitmap fm)   bitmap)
! <register> holds in-store user register for partition
! <bitmap> is partition bitmap


! File system directory formats .....

! Directory header format
%recordformat header fm    (%integer      owner,
                            %integer      password,
                            (%short       perms %c
                             %or %short   files),
                            %short        quota left,
                            %short        spare,
                            %short        directory size)
%constinteger header size = 16

! File header format
%recordformat entry fm     (%integer      name1,
                                          name2,
                            (%short       perms %c
                             %or %short   bytes),
                            (%short       status %c
                             %or %short   time),
                            %short        date,
                            %short        extents)
%constinteger entry size  = 16

! Extent header format
%recordformat extent fm    (%short     start,
                            %short     size)
%constinteger extent size = 4

%constinteger directory size  = 2048 { Bytes }
%constinteger file limit      = (directory size - header size) // entry size
%constinteger extent limit    = (directory size - header size) // extent size

%recordformat directory fm (%record(header fm) header,
                            (%record(entry fm)%array file(1 : file limit) %c
                         %or %record(extent fm)%array extent(1 : extent limit)))


! Directory cache information block

%recordformat dir info fm(%integer              ref count,
                          %integer              written,
                          %integer              partition,
                          %integer              user no,
                          %integer              owner,
                          %integer              stamp,
                          %record(directory fm) d)
! <ref count> tallies users of the directory block
! <written> # 0 if directory has been modified, = 0 otherwise
! <partition> is partition number (within disc) of user
! <user no> is index of user in partition
! <owner> is copy of directory owner field
! <stamp> indicates when directory was last forgotten
! <d> contains data of directory


! Uno and Xno information blocks

%recordformat Uno info fm(%integer                    l owner,
                          %integer                    d owner,
                          %integer                    q pass,
                          %record(dir info fm)%name   l directory,
                          %record(dir info fm)%name   d directory,
                          %integer                    context,
                          %record(stamp fm)           logon stamp,
                          %record(stamp fm)           active stamp,
                          %record(stamp fm)           Xno active stamp)
! <l owner> is current logged-on owner
! <d owner> is default owner
! <q pass> is quoted password
! <l directory> is directory for logged-on owner
! <d directory> is directory for default owner
! <context> is ether context for which Uno is valid (0 for any)
! <logon stamp> indicates when user logged on
! <active stamp> indicates when Uno was last used
! <Xno active stamp> indicates when an Xno belonging to the Uno was used


%recordformat Xno info fm(%integer                    Uno,
                          %record(dir info fm)%name   dir info,
                          %integer                    file slot,
                          ((%integer                  next file block,
                            %integer                  next extent block,
                            %integer                  next disc block,
                            %integer                  extent no) %c
                       %or (%integer                  special buffer,
                            %bytename                 next to send,
                            %integer                  blocks to go,
                            %record(dir info fm)%name forget)),
                          %record(extent fm)          extent,
                          %integer                    extents,
                          %integer                    blocks,
                          %integer                    flags,
                          %integer                    bytes,
                          %integer                    context,
                          %record(stamp fm)           opened stamp,
                          %record(stamp fm)           active stamp)
! <Uno> is user corresponding to this Xno
! <dir info> points to the directory cache slot for this Xno
! <file slot> gives index into directory
! <next file block>, <next extent block> and <next disc block> are
!     next to be read/written for a normal file
! <forget> is directory cache slot to be forgotten when closing Xno
! <special buffer>, <next to send> and <blocks to go> are used
!     when sending special buffers

! <extent> is copy of current extent, indexed by <extent no>
! <extents> is number of extents allocated to file
! <blocks> gives the size of the file
! <flags> contains information on the state of the Xno
! <bytes> gives the length of the last (short) block
! <context> is ether context for which Xno is valid
! <opened stamp> indicates when transaction was opened
! <active stamp> indicates when Xno was last used

%constinteger Xno read  = 1
%constinteger Xno write = 2
%constinteger Xno last  = 4


! Special buffers

%recordformat special fm(%integer bytes, %bytearray b(1 : 4096))


! Common area format

%recordformat common fm(%integer                      proc counter,
                        %integer                      system open,
                        %integer                      system pass,
                        %integer                      ether request queue,
                        %integer                      proc request queue,
                        %integer                      buffer pool used,
                        %integer                      buffer pool free,
                        %integer                      directory stamp,
                        %integer                      diags,
                        %record(monitor fm)           monitor,
                        %integer                      disc twait,
                        %integer                      disc request,
                        %record(ether buffer area fm) ether buffer,
                        %record(port fm)%array        port info(0 : ports),
                        %record(partition fm)%array %c
                                       partition(0 : last partition),
                        %record(dir info fm)%array    dir info(1 : dirs),
                        %record(buffer fm)%array      buffer  (1 : buffs),
                        %record(Uno info fm)%array    Uno     (0 : Unos),
                        %record(Xno info fm)%array    Xno     (1 : Xnos),
                        %record(trace buffer fm)      trace,
                        %record(special fm)%array     specials(1 : specials),
                        %integer                      end)

%constinteger system open    = 16_01
%constinteger allow connects = 16_02
%constinteger allow logins   = 16_04

%constinteger ether     diags = 1
%constinteger proc      diags = 2
%constinteger fsys      diags = 4
%constinteger disc      diags = 8
%constinteger sched     diags = 16
%constinteger sync      diags = 32
%constinteger qsart     diags = 64
%constinteger despool   diags = 128

%end %of %file
