      .title   memory_to_file
;
;     This module consists of two functions:
;
;     INTEGER*4 MEMORY_TO_OLD_FILE(IBEG,IEND,FILENAME)
;        which maps the memory range specified by
;        IBEG to IEND into the existing file whose
;        name is given by FILENAME (must be a
;        CHARACTER variable).  The contents of the
;        memory involved will match the contents of the
;        specified file after this routine is called.
;        In addition, after the program exits (even if
;        aborted) the file will match what was in the
;        specified memory area.
;
;     INTEGER*4 MEMORY_TO_NEW_FILE(IBEG,IEND,FILENAME)
;        which maps the memory range specified by
;        IBEG to IEND into the new file whose
;        name is given by FILENAME (must be a
;        CHARACTER variable).  The memory involved
;        is all zeroed.
;        In addition, after the program exits (even if
;        aborted) the file will match what was in the
;        specified memory area.
;
;
;     Typically these routines are used to map a FORTRAN
;        COMMON block into a file.  In this case there are
;        two restrictions on the COMMON block:
;           1. The length of the block must be extended
;              by an extra 512 bytes beyond the portion of
;              interest.  Since the process of mapping memory
;              into a file happens in 512 byte blocks, this is
;              necessary to ensure that variables outside of the
;              common are not alao mapped into the file.
;              Note that IEND should be the last portion of the
;              common that you are interested in, not the end
;              of the dummy variable you put in.
;           2. The common block must be aligned on a page
;              boundary.  This is accomplished by use of
;              the PSECT_ATTR=common_name,PAGE directive
;              in an options file specified at LINK time, eg.
;                 $ LINK/MAP myprog,mysubs,TT:/OPTION
;                 PSECT_ATTR=common_name,PAGE
;                 ^Z
;
cfab: $FAB  FOP=<UFO,CBT>,FAC=<GET,PUT>,RFM=UDF
memory_to_old_file::
      .word ^m<r2,r3>
      movl  #sec$m_wrt,r2     ; save flags for later use
      clrl  r3                ; remember to open instead of create
      brb   com_code
memory_to_new_file::
      .word ^m<r2,r3>
      movl  #sec$m_wrt!sec$m_dzro,r2     ; save flags for later use
      movzbl   #1,r3          ; remember to open instead of create
com_code:
      ashl  #-9,4(ap),r0      ;note that we can ignore the possibility
      ashl  #-9,8(ap),r1      ;of the sign bit being propagated downward
      subl2 r0,r1             ;since the request will fail for system space
      incl  r1                ;r1 has # of pages
      moval cfab,r0           ;r0 has FAB addr
      $fab_store  alq=r1      ;set up file allocation
      moval @12(ap),r1        ;r1 points to name descriptor
      $fab_store  fns=(r1)    ;store length of name
      $fab_store  fna=@4(r1)  ;store name addr
      blbs  r3,create         ;for new one do a create
      $open fab=cfab          ;open existing file
      brb   fildon            ;skip the create
create:
      $create  fab=cfab       ;create new file
fildon:
      blbc  r0,error          ;check for rms error
      moval 4(ap),r1          ;r1 points to first address
      .list meb
      $crmpsc_s   inadr=(r1),flags=r2,chan=cfab+fab$l_stv
      blbc  r0,error
      ret
error:
      pushl r0
      moval (sp),r2
      pushl r2
      calls #1,errmes
      popl  r0
      ret
      .end
