(FILECREATED " 8-Aug-86 16:40:01" {DSK}<LISPFILES>DOVEFLOPPYPATCH.;2 44773
changes to: (FNS \DOVEFLOPPY.INITDCB)
previous date: "18-Jun-86 16:54:50" {DSK}<LISPFILES>DOVEFLOPPYPATCH.;1)
(* 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 (QUOTE VMEMPAGEP)))
(COND ((EQ (MACHINETYPE)
(QUOTE 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 (* mjs " 8-Aug-86 16:36")
(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. *)
(* * The value of the StepRateTimePlusHeadUnloadTime field below was changed from 177 to 209 on 8/8/86 on
instructions from Cheryl James, based on a message from David Purves.)
(replace (DOVEFLOPPYDCB StepRateTimePlusHeadUnloadTime) of (fetch (DOVEFLOPPYFCB
FLOPPYDCB0BASE)
of \DoveFloppy.FCBPointer)
with 209)
(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 (QUOTE \FLOPPY.SCRATCH.BUFFER2)
(QUOTE RESOURCES)
(QUOTE (NEW (\FLOPPY.BUFFER 4]
)
)
(/SETTOPVAL (QUOTE \\FLOPPY.SCRATCH.BUFFER2.GLOBALRESOURCE))
(SETQ \FLOPPY.SCRATCH.BUFFER2 (NCREATE (QUOTE VMEMPAGEP)))
(COND ((EQ (MACHINETYPE)
(QUOTE DOVE))
(\DOVEFLOPPY.INIT)))
(PUTPROPS DOVEFLOPPYPATCH COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
(FILEMAP (NIL (832 44357 (\DOVEFLOPPY.XFERDISK 842 . 3377) (\DOVEFLOPPY.INITDCB 3379 . 5517) (
\PFLOPPY.FORMAT 5519 . 17203) (\PFLOPPY.GENERATEFILES 17205 . 24377) (\FLOPPY.MOUNTEDP 24379 . 27512)
(\PFLOPPY.SCAVENGE.PMPAGE.AFTER1 27514 . 34556) (\PFLOPPY.OPEN.PFILELIST 34558 . 38353) (
\FLOPPY.TRANSFER 38355 . 44355)))))
STOP