(FILECREATED "18-Jun-86 16:54:50" {ERIS}<LISPCORE>SOURCES>DOVEFLOPPYPATCH.;15 45584  

      changes to:  (VARS DOVEFLOPPYPATCHCOMS)
                   (FNS \DOVEFLOPPY.XFERDISK \DOVEFLOPPY.INITDCB \PFLOPPY.FORMAT 
                        \PFLOPPY.GENERATEFILES \FLOPPY.MOUNTEDP \PFLOPPY.SCAVENGE.PMPAGE.AFTER1 
                        \PFLOPPY.OPEN.PFILELIST \FLOPPY.TRANSFER)

      previous date: "18-Jun-86 10:15:41" {ERIS}<LISPCORE>SOURCES>DOVEFLOPPYPATCH.;14)


(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT DOVEFLOPPYPATCHCOMS)

(RPAQQ DOVEFLOPPYPATCHCOMS ((INITVARS (\DOVEFLOPPY.TRACEFLG NIL))
                              (FNS \DOVEFLOPPY.XFERDISK \DOVEFLOPPY.INITDCB \PFLOPPY.FORMAT 
                                   \PFLOPPY.GENERATEFILES \FLOPPY.MOUNTEDP 
                                   \PFLOPPY.SCAVENGE.PMPAGE.AFTER1 \PFLOPPY.OPEN.PFILELIST 
                                   \FLOPPY.TRANSFER)
                              (GLOBALRESOURCES \FLOPPY.SCRATCH.BUFFER2)
                              (P (SETQ \FLOPPY.SCRATCH.BUFFER2 (NCREATE 'VMEMPAGEP))
                                 (COND ((EQ (MACHINETYPE)
                                            'DOVE)
                                        (\DOVEFLOPPY.INIT))))))

(RPAQ? \DOVEFLOPPY.TRACEFLG NIL)
(DEFINEQ

(\DOVEFLOPPY.XFERDISK
  (LAMBDA (CYL HD SEC BUFF MODE RECAL? RESET?)               (* edited: "23-Mar-86 14:40")
    (PROG (STATUS)
            (SETQ STATUS (\DOVEFLOPPY.TRANSFER CYL HD SEC BUFF MODE RESET? RECAL?))
            (for I from 1 to 50
               do 

          (* * kbr: " 8-Nov-85 12:19" Repeat a few times because of spurious OVERRUN errors. I've also seen a few spurious 
          DATAERRORs. 3 retries is not enough, so I've made it 10.0 *)



          (* * kbr: "19-Mar-86 17:18" Had problems copying an Intellicorp sysout floppy to {DSK}, but if we change the number
          of retries from 10 to 20, the problem (DATAERRORs) goes away. So I've set the number of retries to 40! *)



          (* * kbr: "19-Mar-86 17:18" MESA code uses ActualNumberOfRetriesWhenDMAHit = 50 when handlingError inside 
          UpdateOperation on FLOPPYHEADDOVE.MESA. So I've set the number of retries to 50! *)


                    (COND
                      ((OR (EQ STATUS 'OK)
                             (EQ STATUS 'TIMEOUT))
                        (COND
                          (\DOVEFLOPPY.TRACEFLG (COND
                                                  ((EQ I 1)
                                                    (PRIN1 "." TRACEWINDOW))
                                                  (T (PRIN1 "R" TRACEWINDOW)
                                                     (PRIN1 I TRACEWINDOW)))))
                        (RETURN))
                      (\DOVEFLOPPY.TRACEFLG (PRIN1 STATUS TRACEWINDOW)
                                            (PRIN1 "-" TRACEWINDOW)))
                                                             (* kbr: "19-Mar-86 17:18" Try recalibrating and 
                                                             resetting every fourth time though loop instead of 
                                                             every time through loop. *)
                    (COND
                      ((EQ (IMOD I 4)
                             1)
                        (COND
                          (\DOVEFLOPPY.TRACEFLG (PRIN1 "RECALIBRATE-" TRACEWINDOW)))
                        (SETQ STATUS (\DOVEFLOPPY.TRANSFER CYL HD SEC BUFF MODE T T))
                        (DISMISS 50))
                      (T (SETQ STATUS (\DOVEFLOPPY.TRANSFER CYL HD SEC BUFF MODE NIL NIL)))))
            (RETURN STATUS))))

(\DOVEFLOPPY.INITDCB
  (LAMBDA NIL                                                (* kbr: "20-Apr-86 13:16")
    (replace (DOVEFLOPPYDCB DOOROPEN) of (fetch (DOVEFLOPPYFCB FLOPPYDCB0BASE) of 
                                                                           \DoveFloppy.FCBPointer)
       with 0)
    (replace (DOVEFLOPPYDCB PILOTDISKCHANGED) of (fetch (DOVEFLOPPYFCB FLOPPYDCB0BASE)
                                                        of \DoveFloppy.FCBPointer)
       with 0)
    (replace (DOVEFLOPPYDCB DIAGNOSTICDISKCHANGED) of (fetch (DOVEFLOPPYFCB FLOPPYDCB0BASE)
                                                             of \DoveFloppy.FCBPointer)
       with 0)                                             (* Magic constant 6712 is byteswap of Mesa's 14362 
                                                             magic constant. *)
    (replace (DOVEFLOPPYDCB Port80ControlWord) of (fetch (DOVEFLOPPYFCB FLOPPYDCB0BASE)
                                                         of \DoveFloppy.FCBPointer)
       with 6712)

          (* kbr: "20-Apr-86 13:15" Added the following two replaces. From an INSPECT window I can tell that the value of 
          these fields were 177 and 2, but I have no idea where they originally got set from, and I have looked to try to 
          find out how. According to OSBUNORTH people, HeadLoadTimePlusNotInDMAmode must be 20 to allow 40ms time for head 
          settling before write operations. Without this change, what will happen is that occasionally the DAYBREAK floppy 
          heads will still be vibrating around at the time of the write operation. Later, reads will not be able to read the 
          malformed data and will cause DATAERRORs. *)


    (replace (DOVEFLOPPYDCB StepRateTimePlusHeadUnloadTime) of (fetch (DOVEFLOPPYFCB 
                                                                                   FLOPPYDCB0BASE)
                                                                      of \DoveFloppy.FCBPointer)
       with 177)
    (replace (DOVEFLOPPYDCB HeadLoadTimePlusNotInDMAmode) of (fetch (DOVEFLOPPYFCB 
                                                                                   FLOPPYDCB0BASE)
                                                                    of \DoveFloppy.FCBPointer)
       with 20)))

(\PFLOPPY.FORMAT
  (LAMBDA (NAME AUTOCONFIRMFLG SLOWFLG)                      (* kbr: "18-Jun-86 16:53")
                                                             (* Return T if formatted, NIL if user abort.
                                                             *)
    (PROG (CONFIRM PSECTOR9 PMPAGEA PMPAGEB PMPAGEC PFILELIST PFLE NATTEMPTS NTIMES)
            (SETQ NTIMES 1)
            (\FLOPPY.UNCACHED.WRITE)                       (* Confirmation. *)
            (SETQ CONFIRM (\PFLOPPY.CONFIRM "Destroy contents of floppy" AUTOCONFIRMFLG T))
            (COND
              ((NOT CONFIRM)
                (RETURN NIL)))                             (* Forcibly close floppy. *)
            (\FLOPPY.CLOSE)                                (* Create critical records.
                                                             *)
            (SETQ PFILELIST (\FLOPPY.BUFFER 2))
            (replace (PFILELIST SEAL) of PFILELIST with SEAL.PFILELIST)
            (replace (PFILELIST VERSION) of PFILELIST with VERSION.PFILELIST)
            (replace (PFILELIST NENTRIES) of PFILELIST with 1)
            (replace (PFILELIST MAXENTRIES) of PFILELIST with (IQUOTIENT (IDIFFERENCE
                                                                                   512 4)
                                                                                 5))
            (SETQ PFLE (create PFLE
                                   FILEID ← 1
                                   TYPE ← FILETYPE.PFILELIST
                                   START ← (ADD1 \PFLOPPYFIRSTDATAPAGE)
                                   LENGTH ← 2))
            (\MOVEWORDS PFLE 0 PFILELIST 4 5)
            (SETQ PMPAGEA
              (create PMPAGE
                        PTYPE ← PMPAGEETYPE.FREE
                        PFILEID ← 0
                        PFILETYPE ← FILETYPE.FREE
                        PLENGTH ← 0
                        NTYPE ← PMPAGEETYPE.PFILELIST
                        NFILETYPE ← FILETYPE.PFILELIST
                        NFILEID ← 1
                        NLENGTH ← 2))
            (SETQ PMPAGEB
              (create PMPAGE
                        PTYPE ← PMPAGEETYPE.PFILELIST
                        PFILETYPE ← FILETYPE.PFILELIST
                        PFILEID ← 1
                        PLENGTH ← 2
                        NTYPE ← PMPAGEETYPE.FREE
                        NFILETYPE ← FILETYPE.FREE
                        NFILEID ← 0
                        NLENGTH ← (IDIFFERENCE \PFLOPPYLASTDATAPAGE (IPLUS \PFLOPPYFIRSTDATAPAGE 
                                                                               4))))
            (SETQ PMPAGEC (create PMPAGE
                                      PTYPE ← PMPAGEETYPE.FREE
                                      PFILEID ← 0
                                      PFILETYPE ← FILETYPE.FREE
                                      PLENGTH ← (IDIFFERENCE \PFLOPPYLASTDATAPAGE (IPLUS 
                                                                            \PFLOPPYFIRSTDATAPAGE 4))
                                      NTYPE ← PMPAGEETYPE.FREE
                                      NFILEID ← 0
                                      NFILETYPE ← FILETYPE.FREE
                                      NLENGTH ← 0))
            (SETQ PSECTOR9 (create PSECTOR9
                                       PFILELISTSTART ← (ADD1 \PFLOPPYFIRSTDATAPAGE)
                                       PFILELISTFILEID ← 1
                                       PFILELISTLENGTH ← 2
                                       ROOTFILEID ← 0
                                       NEXTUNUSEDFILEID ← 2))
            (replace (PSECTOR9 $LABEL) of PSECTOR9 with NAME)
                                                             (* Check floppy can write. *)
            (SETQ NATTEMPTS 0)
        RETRY
            (SETQ NATTEMPTS (ADD1 NATTEMPTS))
            (COND
              ((IGREATERP NATTEMPTS 5)
                (\FLOPPY.MESSAGE "Couldn't format floppy")
                (RETURN NIL)))
            (COND
              ((NOT (AND (\FLOPPY.INITIALIZE T)
                             (\FLOPPY.WRITEABLEP)))
                (GO ERROR)))                               (* Configure floppy. *)
            (COND
              ((OR SLOWFLG (NULL PSECTOR9))              (* Format tracks. *)
                (COND
                  ((NOT (AND (\FLOPPY.INITIALIZE T)
                                 (\FLOPPY.RECALIBRATE T)
                                 (GLOBALRESOURCE \FLOPPY.IBMS128.FLOPPYIOCB
                                                 (\FLOPPY.FORMATTRACKS \FLOPPY.IBMS128.FLOPPYIOCB
                                                                         (create DISKADDRESS
                                                                                   CYLINDER ← 0
                                                                                   HEAD ← 0
                                                                                   SECTOR ← 1)
                                                                         1 T))
                                 (GLOBALRESOURCE \FLOPPY.IBMD256.FLOPPYIOCB
                                                 (\FLOPPY.FORMATTRACKS \FLOPPY.IBMD256.FLOPPYIOCB
                                                                         (create DISKADDRESS
                                                                                   CYLINDER ← 0
                                                                                   HEAD ← 1
                                                                                   SECTOR ← 1)
                                                                         1 T))
                                 (\FLOPPY.RECALIBRATE T)
                                 (GLOBALRESOURCE \FLOPPY.IBMD512.FLOPPYIOCB
                                                 (\FLOPPY.FORMATTRACKS \FLOPPY.IBMD512.FLOPPYIOCB
                                                                         (create DISKADDRESS
                                                                                   CYLINDER ← 1
                                                                                   HEAD ← 0
                                                                                   SECTOR ← 1)
                                                                         (SUB1 \FLOPPY.CYLINDERS)
                                                                         T)
                                                 (\FLOPPY.FORMATTRACKS \FLOPPY.IBMD512.FLOPPYIOCB
                                                                         (create DISKADDRESS
                                                                                   CYLINDER ← 1
                                                                                   HEAD ← 1
                                                                                   SECTOR ← 1)
                                                                         (SUB1 \FLOPPY.CYLINDERS)
                                                                         T))))
                    (GO ERROR)))

          (* Check that we can read from each page. We need to do this because FORMATTRACKS (espescially DOVE) is unreliable.
          If we find a bad page, it usually works to try again a few times. We know from experience that the tendency is for 
          an unformatted floppy to become better the more times you format it. *)


                (COND
                  ((GLOBALRESOURCE \FLOPPY.IBMD512.FLOPPYIOCB
                                   (for I from \PFLOPPYFIRSTDATAPAGE to \PFLOPPYLASTDATAPAGE
                                      by (SELECTQ (MACHINETYPE)
                                                      (DOVE 1)
                                                      (DANDELION (COND
                                                                   ((type? PSECTOR9 CONFIRM)
                                                             (* Formatted before. Spot check output of formatting.
                                                             *)
                                                                     19)
                                                                   (T 
                                                             (* Never formatted before. Be more careful.
                                                             *)
                                                                      1)))
                                                      NIL)
                                      thereis (NULL (\PFLOPPY.READPAGENO I 
                                                                           \FLOPPY.SCRATCH.BUFFER T)))
                                   )
                    (\FLOPPY.MESSAGE "Retrying format." PROMPTWINDOW)
                    (GO ERROR)))))                         (* Write PMPAGEs, PFILELIST, and PSECTOR9.
                                                             Write PSECTOR9 last. We check for it first when we 
                                                             open floppy. *)
            (COND
              ((NOT (AND (\PFLOPPY.WRITEPAGENO \PFLOPPYFIRSTDATAPAGE PMPAGEA T)
                             (\PFLOPPY.WRITEPAGENO (ADD1 \PFLOPPYFIRSTDATAPAGE)
                                                     PFILELIST T)
                             (\PFLOPPY.WRITEPAGENO (IPLUS \PFLOPPYFIRSTDATAPAGE 2)
                                                     (\ADDBASE PFILELIST 256)
                                                     T)
                             (\PFLOPPY.WRITEPAGENO (IPLUS \PFLOPPYFIRSTDATAPAGE 3)
                                                     PMPAGEB T)
                             (\PFLOPPY.WRITEPAGENO \PFLOPPYLASTDATAPAGE PMPAGEC T)
                             (GLOBALRESOURCE \FLOPPY.IBMS128.FLOPPYIOCB
                                             (\FLOPPY.WRITESECTOR \FLOPPY.IBMS128.FLOPPYIOCB
                                                                    (create DISKADDRESS
                                                                              CYLINDER ← 0
                                                                              HEAD ← 0
                                                                              SECTOR ← 9)
                                                                    PSECTOR9 T))))
                (GO ERROR)))
            (SETQ NTIMES (SUB1 NTIMES))
            (COND
              ((EQ NTIMES 0)                               (* Successful Return. *)
                (RETURN T))
              (T (GO RETRY)))
        ERROR
            (SETQ SLOWFLG T)
            (COND
              ((EQ (MACHINETYPE)
                     'DOVE)

          (* DOVEFLOPPY formatting is so flakey that if we find any indication of problems in formatting that we then insist 
          that we keep formatting until we can successfully format twice in a row. *)


                (SETQ NTIMES 2)))
            (GO RETRY))))

(\PFLOPPY.GENERATEFILES
  (LAMBDA (FDEV PATTERN DESIREDPROPS OPTIONS)                (* kbr: "22-Mar-86 17:53")
    (WITH.MONITOR \FLOPPYLOCK (PROG (ALLOCS FILTER DESIREDVERSION GENFILESTATE PFALLOC VALIST 
                                              VERSION FILEGENOBJ)
                                                             (* No floppy gives empty directory so that {FLOPPY} 
                                                             can safely be on DIRECTORIES search path.
                                                             *)
                                      (COND
                                        ((EQ (MACHINETYPE)
                                               'DOVE)        (* Patch around DOVE IOP assembly language coded 
                                                             dooropen & diskchangeclear status flags not working.
                                                             *)
                                          (COND
                                            ((NOT (for STREAM in \OPENFILES
                                                       thereis (EQ (fetch (STREAM DEVICE)
                                                                          of STREAM)
                                                                       \FLOPPYFDEV)))
                                                             (* Don't have any open streams to DOVE floppy, so 
                                                             assume that user may have switched floppies.
                                                             *)
                                              (\FLOPPY.CLOSE)))))
                                      (COND
                                        ((AND (\FLOPPY.EXISTSP T)
                                                (\FLOPPY.CACHED.READ T))
                                          (SETQ FILTER (DIRECTORY.MATCH.SETUP PATTERN))
                                          (SETQ DESIREDVERSION (FILENAMEFIELD PATTERN
                                                                                  'VERSION))
                                          (SETQ ALLOCS
                                            (for NBUCKET in (fetch (PFLOPPYFDEV DIR)
                                                                   of \FLOPPYFDEV)
                                               join
                                                (for EBUCKET in (CDR NBUCKET)
                                                   join (COND
                                                            ((FIXP DESIREDVERSION)
                                                              (SETQ PFALLOC
                                                                (CDR (ASSOC DESIREDVERSION
                                                                                (CDR EBUCKET))))
                                                              (COND
                                                                ((AND PFALLOC
                                                                        (DIRECTORY.MATCH
                                                                          FILTER
                                                                          (fetch (PFALLOC FILENAME)
                                                                             of PFALLOC)))
                                                                  (LIST PFALLOC))))
                                                            ((DIRECTORY.MATCH FILTER
                                                                                (CONCAT
                                                                                  (CAR NBUCKET)
                                                                                  "."
                                                                                  (CAR EBUCKET)))
                                                              (COND
                                                                ((NULL DESIREDVERSION)
                                                             (* Highest version only *)
                                                                  (SETQ VALIST (CDR EBUCKET))
                                                                  (SETQ VERSION
                                                                    (\PFLOPPY.DIR.VERSION
                                                                      NIL
                                                                      'OLD VALIST))
                                                                  (SETQ PFALLOC
                                                                    (CDR (ASSOC VERSION VALIST)))
                                                                  (COND
                                                                    (PFALLOC (LIST PFALLOC))))
                                                                (T (for VBUCKET
                                                                      in (CDR EBUCKET)
                                                                      collect (CDR VBUCKET))))))))
                                            )))
                                      (COND
                                        ((MEMB 'SORT OPTIONS)
                                          (SORT ALLOCS (FUNCTION (LAMBDA (X Y)
                                                      (UALPHORDER (fetch (PFALLOC FILENAME)
                                                                       of X)
                                                                    (fetch (PFALLOC FILENAME)
                                                                       of Y)))))))
                                      (SETQ GENFILESTATE (create GENFILESTATE
                                                                     ALLOCS ← ALLOCS
                                                                     DEVICENAME ←
                                                                     (fetch (FDEV DEVICENAME)
                                                                        of FDEV)))
                                      (SETQ FILEGENOBJ (create FILEGENOBJ
                                                                   NEXTFILEFN ←
                                                                   (FUNCTION \PFLOPPY.NEXTFILEFN)
                                                                   FILEINFOFN ←
                                                                   (FUNCTION \PFLOPPY.FILEINFOFN)
                                                                   GENFILESTATE ← GENFILESTATE))
                                      (RETURN FILEGENOBJ)))))

(\FLOPPY.MOUNTEDP
  (LAMBDA (NOERROR)                                          (* edited: "23-Mar-86 15:08")
                                                             (* Floppy drive contains floppy, door is shut, door 
                                                             stable since last \FLOPPY.INITIALIZE? *)
    (PROG (ANSWER)

          (* There is apparently no way to test these facts independently. Also, if DOOROPENED bit was set in the past & 
          floppy is now mounted, this routine treats this as unmounted. Some recovery routine must do a \FLOPPY.INITIALIZE as
          one of its actions to clear this bit. *)


            (SETQ ANSWER (SELECTQ (MACHINETYPE)
                                      (DANDELION (UNINTERRUPTABLY
                                                     (\FLOPPY.NOP T)
                                                     (NOT (fetch (FLOPPYRESULT DOOROPENED)
                                                               of \FLOPPYRESULT))))
                                      (DOVE                  (* MORE UGLY CRUFT TO GET AROUND DOVE DOOROPEN BITS 
                                                             NOT WORKING. *)
                                            (COND
                                              ((for F in \OPENFILES
                                                  thereis (EQ (fetch (STREAM DEVICE)
                                                                     of F)
                                                                  \FLOPPYFDEV))
                                                             (* If the user has streams open on {FLOPPY} then the 
                                                             user probably hasn't switched floppies.
                                                             *)
                                                T)
                                              ((AND (NOT (STKPOS 'FLOPPY.FORMAT))
                                                      (EQ (WITH.MONITOR \FLOPPYLOCK
                                                                          (\DOVEFLOPPY.TRANSFER
                                                                            20 0 1 
                                                                           \FLOPPY.SCRATCH.BUFFER
                                                                            'READDATA))
                                                            'TIMEOUT))

          (* Notice that we obtain \FLOPPYLOCK before doing timeing. Since TIMEOUT can happen if floppy is not formatted 
          properly, just say T if we're underneath FLOPPY.FORMAT. *)


                                                NIL)
                                              (T T)))
                                      NIL))
            (COND
              ((OR NOERROR ANSWER)
                (RETURN ANSWER)))
            (\FLOPPY.BREAK "Door open(ed) or disk missing"))))

(\PFLOPPY.SCAVENGE.PMPAGE.AFTER1
  (LAMBDA (PLOCATION PPMPAGE LOCATION PMPAGE)                (* edited: "23-Mar-86 20:05")
    (PROG (TRIEDWRITING TRIEDFORMATTING OLDPAGES LENGTH TYPE FILETYPE FILEID)
        RETRY
            (COND
              ((NOT (\PFLOPPY.READPAGENO LOCATION PMPAGE T))
                                                             (* Couldn't read this LOCATION.
                                                             Assume misformatted track. *)
                (COND
                  ((NOT TRIEDWRITING)
                    (for I from 0 to 511 do (\PUTBASEBYTE PMPAGE I (CHARCODE " ")))
                    (\PFLOPPY.WRITEPAGENO LOCATION PMPAGE T)
                    (SETQ TRIEDWRITING T)
                    (GO RETRY))
                  ((NOT TRIEDFORMATTING)
                    (GLOBALRESOURCE \FLOPPY.IBMD512.FLOPPYIOCB (SETQ DISKADDRESS (
                                        \PFLOPPY.PAGENOTODISKADDRESS LOCATION))
                                    (SETQ OLDPAGES (for SECTOR from 1 to 
                                                                          \FLOPPY.SECTORSPERTRACK
                                                        collect
                                                         (PROG (OLDPAGE)
                                                                 (SETQ OLDPAGE (NCREATE
                                                                     'VMEMPAGEP))
                                                                 (\FLOPPY.READSECTOR
                                                                   \FLOPPY.IBMD512.FLOPPYIOCB
                                                                   (create DISKADDRESS
                                                                             CYLINDER ←
                                                                             (fetch (DISKADDRESS
                                                                                        CYLINDER)
                                                                                of DISKADDRESS)
                                                                             HEAD ←
                                                                             (fetch (DISKADDRESS
                                                                                        HEAD)
                                                                                of DISKADDRESS)
                                                                             SECTOR ← SECTOR)
                                                                   OLDPAGE T)
                                                                 (RETURN OLDPAGE))))
                                                             (* Since formatting is unreliable, repeat format twice
                                                             in a row. *)
                                    (\FLOPPY.FORMATTRACKS \FLOPPY.IBMD512.FLOPPYIOCB DISKADDRESS 1 
                                                            T)
                                    (\FLOPPY.FORMATTRACKS \FLOPPY.IBMD512.FLOPPYIOCB DISKADDRESS 1 
                                                            T)
                                                             (* Restore what we could salvage before reformatting.
                                                             *)
                                    (for SECTOR from 1 to \FLOPPY.SECTORSPERTRACK as OLDPAGE
                                       in OLDPAGES do (\FLOPPY.WRITESECTOR
                                                            \FLOPPY.IBMD512.FLOPPYIOCB
                                                            (create DISKADDRESS
                                                                      CYLINDER ← (fetch
                                                                        (DISKADDRESS CYLINDER)
                                                                                    of DISKADDRESS)
                                                                      HEAD ← (fetch (DISKADDRESS
                                                                                        HEAD)
                                                                                of DISKADDRESS)
                                                                      SECTOR ← SECTOR)
                                                            OLDPAGE T)))
                    (SETQ TRIEDFORMATTING T)
                    (GO RETRY))
                  (T (\FLOPPY.MESSAGE (CONCAT "Couldn't read or reformat page " LOCATION))
                     (\FLOPPY.MESSAGE "User should not trust this floppy.")
                                                             (* At this point PMPAGE is blank.
                                                             *)
                     (RETURN PMPAGE)))))
            (COND
              ((NOT (OR (fetch (PMPAGE INTACT) of PMPAGE)
                            (IEQP LOCATION \PFLOPPYLASTDATAPAGE)))
                (RETURN)))                                 (* Force PMPAGE to be a legal marker page.
                                                             *)
            (replace (PMPAGE SEAL) of PMPAGE with SEAL.PMPAGE)
            (replace (PMPAGE VERSION) of PMPAGE with VERSION.PMPAGE)
            (SETQ LENGTH (IPLUS LOCATION (IMINUS PLOCATION)
                                    -1))
            (COND
              ((ZEROP LENGTH)
                (SETQ TYPE PMPAGEETYPE.FREE)
                (SETQ FILETYPE FILETYPE.FREE)
                (SETQ FILEID 0))
              (T (SETQ TYPE (fetch (PMPAGE NTYPE) of PPMPAGE))
                 (SETQ FILETYPE (fetch (PMPAGE NFILETYPE) of PPMPAGE))
                 (SETQ FILEID (COND
                     ((EQ TYPE PMPAGEETYPE.PFILELIST)
                       1)
                     (T 0)))))
            (replace (PMPAGE PLENGTH) of PMPAGE with LENGTH)
            (replace (PMPAGE PTYPE) of PMPAGE with TYPE)
            (replace (PMPAGE PFILETYPE) of PMPAGE with FILETYPE)
            (replace (PMPAGE PFILEID) of PMPAGE with FILEID)
                                                             (* Fix PPMPAGE wrt PMPAGE now *)
            (replace (PMPAGE NLENGTH) of PPMPAGE with LENGTH)
            (replace (PMPAGE NTYPE) of PPMPAGE with TYPE)
            (replace (PMPAGE NFILETYPE) of PPMPAGE with FILETYPE)
            (replace (PMPAGE NFILEID) of PPMPAGE with FILEID)
            (\PFLOPPY.WRITEPAGENO PLOCATION PPMPAGE))))

(\PFLOPPY.OPEN.PFILELIST
  (LAMBDA NIL                                                (* kbr: " 7-Aug-85 18:09")
    (PROG (PSECTOR9 PFILELIST FILENAME PMPAGE PLPAGE PFALLOC PFALLOCS)
        RETRY
            (SETQ PSECTOR9 (fetch (PFLOPPYFDEV PSECTOR9) of \FLOPPYFDEV))
            (SETQ PFILELIST (\PFLOPPY.CREATE.PFILELIST (fetch (PSECTOR9 PFILELISTLENGTH)
                                                              of PSECTOR9)))
            (replace (PFLOPPYFDEV PFILELIST) of \FLOPPYFDEV with PFILELIST)
            (replace (PSECTOR9 NEXTUNUSEDFILEID) of PSECTOR9 with 1)
            (for (START ← (ADD1 \PFLOPPYFIRSTDATAPAGE)) by (IPLUS START (fetch
                                                                            (PMPAGE NLENGTH)
                                                                                   of PMPAGE)
                                                                          1)
               do (SETQ PMPAGE (NCREATE 'PMPAGE))
                    (\PFLOPPY.READPAGENO (SUB1 START)
                                           PMPAGE)
                    (COND
                      ((NOT (fetch (PMPAGE INTACT) of PMPAGE))
                        (\PFLOPPY.DAMAGED)
                        (SETQ PFALLOCS NIL)
                        (GO RETRY)))
                    (COND
                      ((EQ (fetch (PMPAGE NFILETYPE) of PMPAGE)
                             FILETYPE.FILE)
                        (SETQ PLPAGE (NCREATE 'PLPAGE))
                        (\PFLOPPY.READPAGENO START PLPAGE)
                        (COND
                          ((NOT (fetch (PLPAGE INTACT) of PLPAGE))
                            (\PFLOPPY.DAMAGED)
                            (SETQ PFALLOCS NIL)
                            (GO RETRY)))
                        (SETQ FILENAME (fetch (PLPAGE $NAME) of PLPAGE)))
                      (T (SETQ PLPAGE NIL)
                         (SETQ FILENAME (LIST (fetch (PMPAGE $NFILETYPE) of PMPAGE)))))
                    (SETQ PFALLOC
                      (create PFALLOC
                                FILENAME ← FILENAME
                                START ← START
                                PMPAGE ← PMPAGE
                                PLPAGE ← PLPAGE))
                    (COND
                      ((NOT (EQ (fetch (PMPAGE NFILETYPE) of PMPAGE)
                                    FILETYPE.FREE))
                        (\PFLOPPY.ADD.TO.PFILELIST PFALLOC)))
                    (push PFALLOCS PFALLOC)
                    (COND
                      ((IEQP START (ADD1 \PFLOPPYLASTDATAPAGE))
                        (RETURN))))
            (SETQ PFALLOCS (DREVERSE PFALLOCS))
            (for PREV in PFALLOCS as NEXT in (CDR PFALLOCS) while NEXT
               do (replace (PFALLOC NEXT) of PREV with NEXT)
                    (replace (PFALLOC PREV) of NEXT with PREV))
            (replace (PFLOPPYFDEV PFALLOCS) of \FLOPPYFDEV with PFALLOCS)

          (* We create the directory last because PACKFILENAME is brittle and it is nice to have the other info already 
          filled in if you have to debug. *)


            (for PFALLOC in PFALLOCS when (EQ (fetch (PFALLOC FILETYPE) of PFALLOC)
                                                      FILETYPE.FILE)
               do (\PFLOPPY.DIR.PUT (fetch (PFALLOC FILENAME) of PFALLOC)
                                        'OLD PFALLOC)))))

(\FLOPPY.TRANSFER
  (LAMBDA (FLOPPYIOCB COMMAND DISKADDRESS PAGE NOERROR)      (* kbr: "17-Apr-86 18:41")
    (PROG (MESSAGE ANSWER)
            (SETQ ANSWER (SELECTQ (MACHINETYPE)
                                      (DANDELION (SETQ COMMAND (SELECTQ COMMAND
                                                                            (READ C.READSECTOR)
                                                                            (WRITE C.WRITESECTOR)
                                                                            (SHOULDNT)))
                                                 (UNINTERRUPTABLY
                                                     (replace (FLOPPYIOCB COMMAND) of FLOPPYIOCB
                                                        with COMMAND)
                                                     (replace (FLOPPYIOCB SUBCOMMAND) of 
                                                                                       FLOPPYIOCB
                                                        with SC.NOP)
                                                     (replace (FLOPPYIOCB DISKADDRESS)
                                                        of FLOPPYIOCB with DISKADDRESS)
                                                     (replace (FLOPPYIOCB BUFFER) of FLOPPYIOCB
                                                        with PAGE)
                                                     (replace (FLOPPYIOCB SECTORCOUNT)
                                                        of FLOPPYIOCB with 1))
                                                 (COND
                                                   ((\FLOPPY.RUN FLOPPYIOCB NOERROR)
                                                             (* Successful coMPletion. *)
                                                     PAGE)))
                                      (DOVE (SETQ COMMAND (SELECTQ COMMAND
                                                                       (READ 'READDATA)
                                                                       (WRITE 'WRITEDATA)
                                                                       (SHOULDNT)))
                                            (\DOVEFLOPPY.SETCONTEXT (fetch (FLOPPYIOCB $DENSITY)
                                                                         of FLOPPYIOCB)
                                                                      (fetch (FLOPPYIOCB 
                                                                             $ENCODEDSECTORLENGTH)
                                                                         of FLOPPYIOCB))
                                            (COND
                                              ((EQ COMMAND 'WRITEDATA)

          (* kbr: "24-Mar-86 01:36" We're going to write a sector on DOVE floppy, but it turns out that DOVE floppy drive 
          heads vibrate when they move and 1 in 5000 times you smash your floppy if you try to move and write with the same 
          operation. We get around this problem by first doing our move during a read operation, which is safe since we are 
          not modifying floppy during a read. After completing the read we do a DISMISS to pass a little time between the 
          read/move and the coming write. I tried running without the DISMISS and do still find occasional long sequences of 
          MISSINGADDRESSMARKs or DATAERRORs in the error log in TRACEWINDOW I get with \DOVEFLOPPY.TRACEFLG = T.
          After 10 hours of filebanging operations, one of the long sequences finally got long enough to break FLOPPY.
          I have not tested yet whether the DISMISS does any good, but I don't think it can hurt. (WHAT A MESS!) *)



          (* kbr: "17-Apr-86 18:38" Message from PURVES.OSBUNORTH AND MCQUILKIN.OSBUNORTH recomends 40 ms settling time for 
          DOVE floppy drive head before writing. Therefore (DISMISS 20) changed to (DISMISS 40) Pray this works.
          *)


                                                (GLOBALRESOURCE \FLOPPY.SCRATCH.BUFFER2
                                                                (\DOVEFLOPPY.XFERDISK
                                                                  (fetch (DISKADDRESS CYLINDER)
                                                                     of DISKADDRESS)
                                                                  (fetch (DISKADDRESS HEAD)
                                                                     of DISKADDRESS)
                                                                  (fetch (DISKADDRESS SECTOR)
                                                                     of DISKADDRESS)
                                                                  \FLOPPY.SCRATCH.BUFFER2
                                                                  'READDATA))
                                                (DISMISS 40)))
                                            (SETQ MESSAGE (\DOVEFLOPPY.XFERDISK
                                                (fetch (DISKADDRESS CYLINDER) of DISKADDRESS)
                                                (fetch (DISKADDRESS HEAD) of DISKADDRESS)
                                                (fetch (DISKADDRESS SECTOR) of DISKADDRESS)
                                                PAGE COMMAND))
                                            (COND
                                              ((EQ MESSAGE 'OK)
                                                PAGE)
                                              ((NOT NOERROR)
                                                (\FLOPPY.BREAK MESSAGE))))
                                      NIL))
            (RETURN ANSWER))))
)
(DECLARE: DONTCOPY 
(DECLARE: EVAL@COMPILE 
(PUTDEF '\FLOPPY.SCRATCH.BUFFER2 'RESOURCES '(NEW (\FLOPPY.BUFFER 4)))
)
)
(/SETTOPVAL '\\FLOPPY.SCRATCH.BUFFER2.GLOBALRESOURCE)
(SETQ \FLOPPY.SCRATCH.BUFFER2 (NCREATE 'VMEMPAGEP))
(COND ((EQ (MACHINETYPE)
           'DOVE)
       (\DOVEFLOPPY.INIT)))
(PUTPROPS DOVEFLOPPYPATCH COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1331 45202 (\DOVEFLOPPY.XFERDISK 1341 . 3876) (\DOVEFLOPPY.INITDCB 3878 . 6362) (
\PFLOPPY.FORMAT 6364 . 18048) (\PFLOPPY.GENERATEFILES 18050 . 25222) (\FLOPPY.MOUNTEDP 25224 . 28357) 
(\PFLOPPY.SCAVENGE.PMPAGE.AFTER1 28359 . 35401) (\PFLOPPY.OPEN.PFILELIST 35403 . 39198) (
\FLOPPY.TRANSFER 39200 . 45200)))))
STOP