// (C) Copyright 1979 Tripos Research Group
//     University of Cambridge
//     Computer Laboratory

// Disc copy program for floppy discs on the 8086
// By default, copies the whole disc.
// Keywords "boot" and "filestore" can be used to cause
// copying of just the bootstrap or filestore areas

SECTION "DiscCopy"

GET "LIBHDR"
GET "IOHDR"

MANIFEST
$(
dkdev   = -2
dcb.wordcount = 13
cylsize = 256*13
lwb.filestore.cyl =   15
upb.filestore.cyl = 76
$)

LET start() BE
 $( LET v = VEC 50
    LET rc = 0
    LET dstr = "DK0:,DK1:"
    LET fromdrive, todrive = 0, 0
    LET cylbuf = 0
    if rdargs("from/a,to/a/k,boot/s,filestore/s", v, 50)=0 DO
       error("bad args*N")
    // Default is whole disc
    UNLESS v!2 | v!3 DO v!2, v!3 := TRUE, TRUE
    fromdrive := findarg(dstr, v!0)
    IF fromdrive=-1 DO
       error("unrecognised device %S*N", v!0)
    todrive := findarg(dstr, v!1)
    IF todrive=-1 DO
       error("unrecognised device %S*N", v!1)
    cylbuf := getvec(cylsize-1)
    IF cylbuf=0 DO
       error("can*'t get buffer space*N")

    $( LET lwbcyl = v!2 -> 0, lwb.filestore.cyl
       LET upbcyl = v!3 -> upb.filestore.cyl, lwb.filestore.cyl-1
       FOR cyl = lwbcyl TO upbcyl DO
       $( LET n = 1
          UNTIL sendpkt(-1, dkdev, act.read, 0, 0,
                    cylbuf, cylsize, fromdrive, cyl, 0, 0)=0 DO
          $( n := n+1
             IF n>=10 DO
             $( writef("Read from cylinder %N failed*N", cyl)
                rc := 10
                GOTO L $)
          $)
          IF n>1 DO
          $( writef("Read from cylinder %N took %N tries*N", cyl, n)
             IF rc<5 DO rc := 5 $)
          IF testflags(1) DO
          $( rc := 10
             GOTO L $)
          n := 1
          UNTIL sendpkt(-1, dkdev, act.write, 0, 0,
                    cylbuf, cylsize, todrive, cyl, 0, 0)=0 DO
          $( n := n+1
             IF n>=10 DO
             $( writef("Write to cylinder %N failed*N", cyl)
                rc := 10
                GOTO L $)
          $)
          IF n>1 DO
          $( writef("Write to cylinder %N took %N tries*N", cyl, n)
             IF rc<5 DO rc := 5 $)
       $)
 L: $)
    freevec(cylbuf)
    stop(rc)
 $)


AND error(f, a) BE
 $( writes("DISCCOPY: ")
    writef(f, a)
    stop(20)
 $)