! K Yarwood has some text describing these routines from an operational point
! of view. And the filename is ERCC10.TEXTFILE_FTODTEXT

const  string (19) vsn="04 Mar 85"

const  integer  sectsi=32 {pgs}
const  integer  bitmap pages=5
const  string  (5) index file="SS#INDEX", bmfile="SS#BITMAP"
const  integer  ixpages=16

record  format  parmf(integer  dest, srce, p1, p2, p3, p4, p5, p6)
record  format  srcf(integer  nextfreebyte, txtrelst, maxbytes, zero)


record  format  daf(integer  sectsi, nsects, lastsect, spare, integer  array  da(0:255))
record  format  shortdaf(integer  sectsi, nsects, lastsect, spare, integer  array  da(0:15))
record  format  faf(string  (6) user, string  (15) file,
integer  fsys, record  (shortdaf) fda)
record  format  fff(integer  nfiles, record  (faf) array  f(1:255))


external  routine  spec  dout(record  (parmf) name  p)
external  routine  spec  dout11(record  (parmf) name  p)
external  integer  fn  spec  dsysad(integer  type, adr, fsys)
external  integer  fn  spec  dcreate(string  (6) user, string  (15) file, integer  fsys, nkb, type)
external  integer  fn  spec  ddestroy(string  (31) file index, file, string  (8) date,
    integer  fsys, type)
external  integer  fn  spec  exist(string  (255) s)
system  routine  spec  phex(integer  i)
external  integer  fn  spec  fbase(integer  name  lo, hi, integer  fsys)
external  integer  fn  spec  bin(string  (255) s)
external  routine  spec  rdint(integer  name  i)
external  integer  fn  spec  rdfilead(string  (255) s)
external  integer  fn  spec  nwfilead(string  (255) s, integer  pages)
external  routine  spec  ddelay(integer  secs)
external  routine  spec  disconnect(string  (255) s)
external  routine  spec  prompt(string  (255) s)
external  routine  spec  ucstrg(string  name  s)
external  integer  fn  spec  uinfi(integer  i)
external  string  fn  spec  uinfs(integer  i)
external  integer  fn  spec  derror(string  name  txt)
system  string  fn  spec  itos(integer  value)
system  string  fn  spec  htos(integer  i, pl)
external  routine  spec  destroy(string  (255) s)
dynamic  integer  fn  spec  dgetda(string  (6) user, string  (15) file, integer  fsys, adr)


record  format  discdataf(integer  start, bitsize, nntstart, nntsize, nnttop, nnthash,
    indexstart, filestart, end)
integer  fn  fbase2(integer  fsys, adr)
!
! This returns the characteristics of an on-line disc in a record
! of format DATAF at address ADR
integer  j, lob, hib, type, k
record  (discdataf) name  data
const  integer  toptype= 5
const  integer  array  bitsize(1:top type)= X'1000'(2), X'2000'(2), X'5000'
const  integer  array  nntstart(1:top type)= X'7000'(4), X'A000'
const  integer  array  nntsize(1:top type)= X'4000'(4), X'1FF8'
const  integer  array  nnttop(1:top type)= 1364(4), 681
const  integer  array  nnthash(1:top type)= 1361(4), 667
const  byte  array  indexstart(1:top type)= 12(5)
const  integer  array  filestart(1:top type)= 1024(5)
const  integer  array  hi(1:top type)= X'3F1F', X'59F3', X'8F6F',
                  X'B3E7', X'24797'
   j=fbase(lob, hib, fsys)
   result =j unless  j=0

   type=-1
   cycle  k=1, 1, top type
      type=k and  exit  if  hib=hi(k)
   repeat 
   result =8 if  type<0

   data==record(adr)

   data_start=lob
   data_bitsize=bitsize(type)
   data_nntstart=nntstart(type)
   data_nntsize=nntsize(type)
   data_nnttop=nnttop(type)
   data_nnthash=nnthash(type)
   data_indexstart=index start(type)
   data_filestart=file start(type)
   data_end=hib
   result =0
end ; ! FBASE2
routine  wrs(string  (255) s)
   printstring(s)
   newline
end ; ! WRS
!
!------------------------------------------------------------------------
!
routine  wrsn(string  (255) s, integer  n)
   printstring(s)
   write(n, 1)
   newline
end ; ! WRSN
routine  wrsnt(string  (255) s, integer  n, type)
integer  j
switch  sw(0:3)

!     type & 3 = 0 decimal if small else hex
!                1 decimal
!                2 hex
!                3 decimal and hex
!     type & 4 = 1 dont put NL at end
!     type & X70 gives number of digits, 0=8
   printstring(s)
   space
   ->sw(type&3)
sw(0):->sw(2) unless -256<=n<=255
sw(3):
sw(1):printstring(itos(n))
   ->out if  type&2=0
sw(2):printstring("X'")
   j=type>>4&7
   j=8 if  j=0
   printstring(htos(n, j))
out:
   newline if  type&4=0
end ; ! OF WRSNT

!------------------------------------------------------------------------
!
routine  vvderrs(string  (255) s, integer  j)
string  (255) txt
   return  if  j=0
   j=derror(txt)
   printstring(s)
   space
   wrs(txt)
end ; ! VVDERRS
!
!------------------------------------------------------------------------
!
routine  error
integer  j
string  (255) txt
   j=derror(txt)
   wrs(txt)
end ; ! error

integer  fn  yn(string  (255) pp, integer  a, b)
integer  ch
string  (255) s
   if  a=b=0 then  a='Y' and  b='N'
   prompt(pp)
   cycle 
      ucstrg(s)
      ch=charno(s, 1)
      exit  if  ch=a or  ch=b
   repeat 
   result =ch
end  {yn}

integer  fn  move section(integer  fsys1, startp1, fsys2, startp2, epgs)
integer  fromdev, fsys, bitno, relpage, move flag, rw, fail
integer  j
integer  name  f, page
record  (parmf) p
   unless  startp1>>19=0 and  startp2>>19=0 start 
      wrsnt("MVSC P1", startp1, 6)
      wrsnt(" P2", startp2, 2)
      result =25
   finish 

   printstring("MOVE SECTION  ")
   write(fsys1, 1); space; phex(startp1); write(fsys2, 1); space; phex(startp2)
   write(epgs, 1)
   newline
!  printstring("Moving..")
!  newline

   from dev=2; ! disc
   if  fsys1=-1 start 
      fromdev=5; ! "LP"
      startp1=0
   finish 
!
! OUT TO LOCAL CONTROLLER TO CHECK THAT THE BLOCK WHOSE START PAGE IS
! "PAGE" IS NOT STILL ACTIVE. THIS IS BECAUSE AN ORDINARY DISCONNECT DOES
! NOT WAIT UNTIL ALL PAGE-OUTS ARE COMPLETE.
! But we suppress this check for UNPRG, so that we can unprg active software
! without messages. This is indicated by the TOP BIT being set in FSYS1.
! (This feature is used only by function DPRGP).

   j=0
   f==fsys1
   page==startp1
l:

   if  j=0 start 
      j=1
      f==fsys2
      page==startp2
      ->l
   finish 

   p=0
   p_dest=X'00240000'
   p_p1=X'00020000'!(fromdev<<24)!epgs
   p_p2=fsys1
   p_p3=startp1
   p_p4=fsys2
   p_p5=startp2
   p_p6=M'KYAR'
   if  epgs<5 then  dout11(p) else  dout(p)
   move flag=p_p1
!-----------------------------------------------------------------------
! About the BULK MOVER:
!       CALLED ON SERVICE 36 TO TRANSFERS GROUPS OF PAGES BETWEEN     *
!       FAST DEVICES. REPLIES ARE ON SERVICE 37.                      *
!       FAST DEVICE TYPES ARE:-                                       *
!       DEV=1 DRUM     (SPECIFIED AS SERVICE & PAGE IN AMEM )         *
!       DEV=2 DISCFILE (SPECIFIED AS [MNEMONIC OR LVN] & PAGE)        *
!       DEV=3 ARCHTAPE (SPECIFIED AS SERVICE(PREPOSND BY VOLUMS))     *
!       DEV=4 TAPE     (SPECIFIED AS STRING(6)LAB,BYTE CHAP NO)       *
!       DEV=5 FUNNY    (READS GIVE ZERO PAGE,WRITES IN HEX TO LP)     *
!       DEV=6 SINK       (THROWS AWAY INPUT FOR TAPE CHECKING)        *
!                                                                     *
!       CAN HANDLE UP TO FOUR MOVES AT A TIME. EACH MOVE USES         *
!       ONE BUFFER AND APART FROM CLEARS ONLY HAS ONE TRANSFER        *
!       OUTSTANDING AT ANY ONE TIME TIME.                             *
!       ALL WRITES ARE CHECKED BY RE-READING                          *
!       Failure flags (returned in P_P1) are as follows (at least     *
!       for moves to/from disc):                                      *
!                                                                     *
!       P_P1 = RW<<24  !  FAIL<<16  !  RELPAGE                        *
!                                                                     *
!       where  RW = 1  means a READ failed                            *
!                   2  means a WRITE failed.                          *
!              FAIL = flag from PDISC:                                *
!                         1 = transferred with errors (i.e. cyclic    *
!                             check fails)                            *
!                         2 = request rejected                        *
!                         3 = transfer not effected (e.g. flagged     *
!                             track encountered)                      *
!          and RELPAGE = relative page no of failing page, counting   *
!                        first page of request as one.               *
!----------------------------------------------------------------------
   result =0 if  move flag=0

   rw=move flag>>24
   fail=(move flag>>16)&255
   relpage=move flag&X'FFFF'
   if  ((rw=1 and  fsys1>=0) or  rw=2) and  (fail=1 or  fail=3) start 
      if  rw=1 start 
         fsys=fsys1
         bitno=startp1
      finish  else  start 
         fsys=fsys2
         bitno=startp2
      finish 
      printstring("bad page(1, fsys, bitno+relpage-1)")
      printstring("  Fsys="); write(fsys, 1); space
      printstring("  Page "); phex(bitno+relpage-1)
      newline
   finish 
   result =25
end ; ! MOVE SECTION

routine  fred
   printstring("There are two flavours:  A.  Move pages from a given disc address on an on-line
")
   printstring("                             (but not necessarily CCKed) disc into a file in
")
   printstring("                             the caller's index.
"); printstring("                         B.  Complete a pseudo-import onto DEVV98 (first part of
")
   printstring("                             import is done with command FILESTODISC).
")
end  {fred}

routine  spec  finish import
!-------------------------------------------------------------------------------


external  routine  disctofile(string  (255) s)
integer  from fsys, to fsys, pages, sect, j, pgs, startpage, endpage, totpgs, relpg, ch
string  (63) file
record  (daf) darec

   fred
   ch=yn("Which flavour? ", 'A', 'B')
   if  ch='B' then  finish import and  return 

   prompt("From Fsys: ")
   rdint(from fsys)
   prompt("Start pageno: ")
   rdint(startpage)
   prompt("No of pages: ")
   rdint(pages)
   endpage=startpage+pages-1
   prompt("To file: ")
   ucstrg(file)

   if  exist(file)#0 start 
      ch=yn(file." exists. Destroy? ", 0, 0)
      if  ch='N' then  return 
      destroy(file)
   finish 

   to fsys=uinfi(1)
   j=dcreate(uinfs(1), file, to fsys, pages<<2 {Param is Kbytes}, 4 {zero it})
   if  j#0 start 
      vvderrs("DCREATE", j)
      return 
   finish 

   j=dgetda(uinfs(1), file, to fsys, addr(darec))
   if  j#0 start 
      vvderrs("DGETDA", j)
      return 
   finish 

   totpgs=0
   relpg=0

   for  sect=0, 1, darec_nsects-1 cycle 
      if  sect=darec_nsects-1 then  pgs=darec_lastsect else  pgs=sectsi
      j=move section(from fsys, startpage+relpg, to fsys, darec_da(sect)<<8>>8, pgs)
      if  j#0 start 
         printstring("Flag ")
         write(j, 1)
         printstring(" from MOVE SECTION")
         newline
         return 
      finish 

      relpg=relpg+sectsi
      totpgs=totpgs+pgs
   repeat 

   printstring("DISCTOFILE finished.")
   write(totpgs, 4)
   printstring(" pages moved")
   newline
end  {disc to file}


!-------------------------------------------------------------------------------


external  routine  filestodisc(string  (255) s)

integer  to fsys, from fsys, j, ixfad, lo, hi, totsects, reclen, bmfad, xexit, sect, fileno, pgs,
    freesects, bmptr, nfiles
integer  startp1, lastsect, bmpg

string  (63) user, file

record  (discdataf) data
record  (fff) name  f
record  (faf) ff
record  (faf) name  fent
record  (srcf) name  h
record  (daf) darec, bitmap darec


   printstring("Version ".vsn)
   newline
   ! Make an index file
   ixfad=nwfilead(index file, ixpages)
   if  ixfad=0 start 
      printstring("[Failed to create an index file]")
      newline
      return 
   finish 

   if  exist(bmfile)#0 start 
      !printstring(bmfile." already exists.")
      !newline
      !j=yn("Destroy? ", 0, 0)
      {%if j='Y' %then} destroy(bmfile)
   finish 

   ! Make a file to hold a copy of the bitmap of the destination disc
   j=dcreate(uinfs(1), bmfile, uinfi(1), bitmap pages<<2 {Param is Kbytes}, 4 {zero it})
   if  j#0 start 
      vvderrs("DCREATE", j)
      return 
   finish 

   j=dgetda(uinfs(1), bm file, uinfi(1), addr(bitmap darec))
   if  j#0 start 
      vvderrs("DGETDA", j)
      return 
   finish 

   h==record(ixfad)
   h_maxbytes=ixpages<<12
   f==record(ixfad+h_txtrelst)
   h_nextfreebyte=addr(f_f(1))-ixfad
   reclen=sizeof(ff)

   prompt("To Fsys: ")
   cycle 
      rdint(to fsys)
      if  to fsys#98 start 
         printstring("Fsys must be on-line, NOT CCKed, and must be 98 !!")
         newline
      finish  else  exit 
   repeat 

   j=fbase2(to fsys, addr(data))
   if  j#0 start 
      printstring("FBASE fails for fsys"); write(to fsys, 1)
      printstring("  Flag ="); write(j, 1)
      printstring("  Is the disc on-line?")
      newline
   finish 

   lo=(data_start+data_filestart)>>3; ! byte offset from start of bitmap of the
   ! first bit which is available for
   ! allocation to user files
   hi=data_end; ! END OF USER FILES
   hi=(hi-(sectsi-1))&(¬(sectsi-1))
   hi=hi>>3

   bmpg=data_start

   ! Get bitmap for "ToFsys"
   printstring("Get bitmap for FSYS"); write(TO fsys,1)
   newline
   j=move section(to fsys, bmpg, uinfi(1), bitmap darec_da(0)<<8>>8, bitmap pages)
   if  j#0 start 
      printstring("Flag ")
      write(j, 1)
      printstring(" from MOVE SECTION")
      newline
      return 
   finish 

   bmfad=rdfilead(bmfile)
   return  if  bmfad=0

   prompt("From Fsys: ")
   rdint(from fsys)
   printstring("In the following cycle of collecting filenames for transfer, you can type
""FSYS=n"" to change the current From Fsys. The last-specified username is
remembered.")
   newline

   prompt("File/.END/FSYS=n: ")
   user=""
   xexit=0
   totsects=0

   cycle 
      ucstrg(s)
      if  length(s)>=2 and  substring(s, 1, 2)=".E" start 
         s=uinfs(1).".".index file
         xexit=1
         from fsys=uinfi(1)
      finish 
      if  length(s)>5 and  substring(s, 1, 5)="FSYS=" start 
         s=substring(s, 6, length(s))
         j=bin(s)
         if  0<=j<=99 then  from fsys=j else  printstring("Invalid Fsys number") and  newline
         continue 
      finish 

      if  s->user.(".").file and  length(user)=6 and  file#"" start 
         printstring("Current username is ".user)
         newline
      finish  else  if  user="" start 
         printstring("Give full username.filename to start with")
         newline
         continue 
      finish  else  file=s

      j=dgetda(user, file, from fsys, addr(darec))
      if  j#0 start 
         vvderrs("Flag from DGETDA", j)
         printstring("[Is the ""From"" FSYS correct?]")
         newline
         continue 
      finish  else  start 
         if  darec_nsects>16 start 
            printstring("Sorry: can only handle files having fewer than 16
            sections, and this one")
            newline
            printstring("has"); write(darec_nsects, 1)
            newline
            continue 
         finish 

         f_nfiles=f_nfiles+1
         f_f(f_nfiles)_user=user
         f_f(f_nfiles)_file=file
         f_f(f_nfiles)_fsys=from fsys
         f_f(f_nfiles)_fda<-darec
         totsects=totsects+darec_nsects

         h_nextfreebyte=h_nextfreebyte+reclen

         printstring("File ".user.".".file)
         spaces(12-length(file))
         printstring("from fsys"); write(from fsys, 1)
         printstring(":"); write(darec_nsects, 1); printstring(" section")
         if  darec_nsects>1 then  printstring("s")
         newline

         if  h_nextfreebyte+reclen>h_maxbytes start 
            printstring("The file of file-descriptors is now full")
            newline
            exit 
         finish 
      finish 
   repeat  until  xexit#0

   nfiles=f_nfiles
   ! We do not want to retrieve the index file (it's disc address will be
   ! wrong, because it's written out before it's disc address is updated.
   ! So we decrement the count on disc.
   f_nfiles=f_nfiles-1
   write(nfiles-1, 4)
   printstring(" files (plus index file),")
   write(totsects, 4)
   printstring(" sections, to be moved")
   newline

   return  if  nfiles=0

   ! Are there enough free sects on To Fsys?
   free sects=0
   bmptr=hi+4
   cycle 
      bmptr=bmptr-4
      if  integer(bmfad+bmptr)=0 then  free sects=free sects+1
   repeat  until  {free sects>=totsects %or}bmptr=lo

   if  free sects<totsects then  printstring("...but only") else  printstring("There are")
   write(free sects, 4)
   printstring(" free sections on To Fsys")
   newline
   return  if  free sects<totsects

   !--------------------------- So move the files ----------------------------------
   
   bmptr=hi+4
   for  fileno=1, 1, nfiles cycle 

      fent==f_f(fileno)
      user=fent_user
      file=fent_file
      from fsys=fent_fsys

      lastsect=fent_fda_nsects-1
      for  sect=0, 1, lastsect cycle 
         ! Find a hole (from top)
         cycle 
            bmptr=bmptr-4
            exit  if  integer(bmfad+bmptr)=0
         repeat  until  bmptr<=lo {shouldn't be!}
         if  bmptr<=lo start 
            printstring("What?  No free sections ??")
            newline
            return 
         finish 

         if  sect=lastsect then  pgs=fent_fda_lastsect else  pgs=sectsi
         startp1=fent_fda_da(sect)<<8>>8

         if  fileno=nfiles start 
            printstring("We are DISCONNECTing the index file and DDELAYing 15 secs")
            newline
            disconnect(index file)
            ddelay(15)
         finish 

         j=move section(from fsys, startp1, to fsys, bmptr<<3, pgs)
         if  j#0 start 
            printstring("Move Section fails"); write(j, 1)
            printstring(" for file number"); write(fileno, 1)
            newline
            return 
         finish 

         ! Place disc address into the record entry in the index file.
         ! This is, of course, too late in the case of the index file itself.
         ! We print out the disc address for the operator to type in to the
         ! FINISHIMPORT program (DISCTOFILE).

         if  file=index file and  user=uinfs(1) start 
            printstring("The key disc address, to be given to the FINISHIMPORT program is:")

            s=htos(bmptr<<3, 8)
            while  length(s)>2 and  charno(s, 1)='0' cycle 
               s=substring(s, 2, length(s))
            repeat 
            newlines(2)
            spaces(15); printstring("************"); newline
            spaces(15); printstring("*  X".s); spaces(7-length(s)); printstring("*")
            newline
            spaces(15); printstring("************"); newlines(2)

         finish  else  fent_fda_da(sect)=(to fsys<<24)!(bmptr<<3)

      repeat  {sects in file}
      printstring("File no"); write(fileno, 1)
      printstring("  ".user.".".file); spaces(12-length(file))
      printstring("moved OK")
      newline
   repeat  {files}
   printstring("FILESTODISC completed OK")
   newline
end  {filestodisc}

!-------------------------------------------------------------------------------



external  routine  finish import
! This routine runs on the DEVV98 system
integer  from fsys, to fsys, pages, sect, j, pgs, startpage, endpage, totpgs, relpg, ch, base page
integer  ixfad, lo, hi, ixstartp, bmptr, fileno, bmfad, lastsect, nerrs, prevsect, discad,
    srce fsys, err
string  (63) file, user, wk
record  (daf) darec, ix darec
integer  array  bitmap(0:5119)

record  (discdataf) data
record  (fff) name  f
record  (faf) name  ff
record  (faf) name  fent
record  (srcf) name  h

   file=uinfs(1).".".index file
   if  exist(file)#0 start 
      printstring(file." already exists.")
      newline
      j=yn("Destroy? ", 0, 0)
      if  j='Y' then  destroy(file)
   finish 

   ! First re-create the index file. Not to exceed one section.
   j=dcreate(uinfs(1), index file, uinfi(1), ixpages<<2 {Param is Kbytes}, 4 {zero it})
   if  j#0 start 
      vvderrs("DCREATE", j)
      return 
   finish 

   j=dgetda(uinfs(1), index file, uinfi(1), addr(ix darec))
   if  j#0 start 
      vvderrs("DGETDA", j)
      return 
   finish 
   ixstartp=ix darec_da(0)<<8>>8

   prompt("Into what Fsys? ")
   rdint(to fsys)

   printstring("[Source fsys is 98]")
   newline

   srce fsys=98

   bmfad=addr(bitmap(0))
   j=dsysad(0, bmfad, srce fsys)
   if  j#0 start 
      printstring("Source fsys(98) not available? DSYSAD flag =")
      write(j, 1)
      newline
      return 
   finish 

   prompt("Give the hex key printed by FILESTODISC: ")
   rdint(base page)

   j=fbase2(srce fsys, addr(data))

   if  j#0 start 
      printstring("Flag"); write(j, 1)
      printstring(" from FBASE2.  Is disc on-line??")
      newline
      return 
   finish 

   lo=data_start+data_filestart; ! START DISC ADDR OF USER FILES
   hi=data_end; ! END DISC ADDR OF USER FILES
   hi=(hi-(sectsi-1))&(¬(sectsi-1))

   ! First retrieve the index file
   j=move section(srce fsys, base page, uinfi(1), ixstartp, ixpages)
   if  j#0 start 
      printstring("Move Section fails"); write(j, 1)
      newline
      return 
   finish 

   ixfad=rdfilead(index file)
   return  if  ixfad=0

   f==record(ixfad+integer(ixfad+4))

   ! Prove that the index file is valid and all bits are unset for imported file pages
   nerrs=0
   prevsect=10000000 {using this to show that sect addrs are monotonically decreasing}

   write(f_nfiles, 1)
   printstring(" files to be moved")
   newline
   unless  0<f_nfiles<=100 start 
      write(f_nfiles, 1)
      printstring(" files to be moved?  Too many?  Invalid index file??")
      newline
      return 
   finish 

   ! Continue to check "index" validity

   for  fileno=1, 1, f_nfiles cycle 
      ff==f_f(fileno)
      unless  0<length(ff_user)<=6 and  0<length(ff_file)<=11 start 
         printstring("****index file error********")
         newline
         monitor 
         return 
      finish 
      user=ff_user
      file=ff_file
      printstring("File no"); write(fileno, 1)
      printstring("  ".user.".".file)
      write(ff_fda_nsects, 12-length(file))
      printstring("  sections,")
      write((ff_fda_nsects-1)*sectsi+ff_fda_lastsect, 1); printstring(" pages")
      newline
      lastsect=ff_fda_nsects-1
      for  sect=0, 1, lastsect cycle 
         ! Show that bits are not set.
         discad=ff_fda_da(sect)<<8>>8
         err=0
         if  integer(bmfad+discad>>3)#0 start 
            err=1
            nerrs=nerrs+1
            printstring("***********bits set********")
            newline
         finish 
         unless  discad<prevsect start 
            err=1
            nerrs=nerrs+1
            printstring("Section addresses not monotonically decreasing")
            newline
         finish 
         unless  discad>lo start 
            err=1
            nerrs=nerrs+1
            printstring("********** Disc address below file-start address ***")
            newline
         finish 
         if  err#0 start 
            printstring("Discad: ")
            phex(discad); newline
         finish 
         prevsect=discad
         exit  if  nerrs>10
      repeat  {sects in file}
      exit  if  nerrs>10
   repeat  {files}

   if  nerrs#0 start 
      printstring("At least")
      write(nerrs, 1)
      printstring(" errors found. Cannot continue")
      newline
      return 
   finish  else  start 
      printstring("Starting to move files")
      newline
   finish 

   ! Move the files.  Start at lowest to minimise risk of overwriting own
   ! files on a very full disc
   
   for  fileno=f_nfiles, -1, 1 cycle 
      ff==f_f(fileno)
      user=ff_user
      file=ff_file
      wk=user.".".file
      pages=(ff_fda_nsects-1)*sectsi+ff_fda_lastsect

recreate:
      j=dcreate(user, file, to fsys, pages<<2 {Param is Kbytes}, 4 {zero it})
      if  j=37 start 
         printstring("User ".user." not found (on Fsys"); write(to fsys, 1)
         printstring(")."); newline
         ch=yn("Give alternative?y/n", 0, 0)
         if  ch='N' start 
            printstring("File omitted")
            newline
            continue 
         finish  else  start 
            prompt("Username: ")
            ucstrg(user) until  length(user)=6
            ->recreate
         finish 
      finish 
      if  j=16 start 
         printstring(wk." exists  on fsys ".itos(to fsys))
         newline
         ch=yn("Destroy?", 0, 0)
         if  ch='N' start 
            printstring("File not moved")
            newline
            continue 
         finish 
         j=ddestroy(user, file, "", to fsys, 0)
         if  j=0 then  ->recreate
         vvderrs(wk, j)
         return 
      finish 

      if  j#0 start 
         vvderrs(wk, j)
         return 
      finish 

      j=dgetda(user, file, to fsys, addr(darec))
      if  j#0 start 
         vvderrs(wk, j)
         return 
      finish 

      for  sect=0, 1, ff_fda_nsects-1 cycle 
         if  sect=lastsect then  pgs=ff_fda_lastsect else  pgs=sectsi
         j=move section(srce fsys, ff_fda_da(sect)<<8>>8, to fsys, darec_da(sect)<<8>>8, pgs)
         if  j#0 start 
            printstring("Move Section fails"); write(j, 1)
            printstring(" fo file number"); write(fileno, 1)
            newline
            return 
         finish 
      repeat  {sects in file}
      printstring("File no"); write(fileno, 1)
      printstring("  ".user.".".file); spaces(12-length(file))
      printstring("moved OK")
      newline
   repeat  {files}

   printstring("FILESTODISC completed")
   newline
end  {finish import}

external  routine  filetodisc(string  (255) s)
   filestodisc(s)
end  {filetodisc}

external  routine  disctofiles(string  (255) s)
   disctofile(s)
end  {disctofiles}

end  of  file