boot3/Toolbox/DiskInit/DiskInit.a

1775 lines
84 KiB
Plaintext
Raw Normal View History

;
; File: DiskInit.a
;
; Contains: Disk Initialization package (for Sony drives)
;
; Copyright: <09> 1983-1992 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <33> 4/28/92 DTY Get rid of BadBlockSparingEnabled conditional.
; <32> 2/10/92 JSM Moved this file to DiskInit folder, keeping all the old
; revisions.
; <31> 10/28/91 SAM/KSM Rolled in Regatta change:
; The format code has been changed to assume MFS format if the #
; of blocks on the disk is *exactly* 800. This prevents a small
; EDisk getting formatted as MFS (cuz 800 blocks is an invalid
; EDisk size).
; <30> 8/30/91 DTY Define has3rdFloppy here since it<69>s no longer defined in
; BBSStartup.
; <29> 7/2/91 JSM Remove obsolete 7.0 related SysVers conditionals.
; <28> 6/12/91 LN Removed #includes for private interfaces from public interfaces.
; Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
; <27> 2/21/91 KST dnf, #81502: Convert positive (internal) error code to negative.
; <26> 2/8/91 KST ewa, #78956: DIZero will do disk sparing.
; <25> 2/8/91 KST ewa, #81501: diZero will return error code when called in
; DIBadMount.
; <24> 2/8/91 KST ewa, #81502: DIBadMount will return correct error code.
; <23> 1/24/91 KST With BB, #81501: DIZero will check for return error.
; <22> 11/27/90 dnf/sad For 7.0, Don't adjust dialog position using user's passed-in
; point. We use the dialog centering code now.
; <21> 9/16/90 BB Fix disk init bug causing floppies to be ejected ahead
; of their time.
; <21> 9/16/90 BB Fixed bug causing the before and after checksums to different
; when insuring the correct disk is still in the drive. TestVol
; now does a FlushVol.
; <20> 9/13/90 BG Removed <14>. 040s are behaving more reliably now.
; <19> 8/28/90 PK Bug fix: single-sided button was broken by <15>, now works
; again.
; <18> 8/27/90 PK Forgot to update Rev4DITLlen in last change.
; <17> 8/27/90 PK Special check and msg for future volume formats.
; <16> 8/24/90 PK Get rid of balloons while formatting.
; <15> 8/7/90 PK Added last-minute check to be sure the correct disk is still in
; the drive, to avoid inadvertent initialization of boot disk.
; BBS bad block sparing feature now enabled for 7.0.
; <14> 7/16/90 BG Added EclipseNOPs for flakey 040s.
; <13> 7/11/90 gbm make changes to facilitate the elimination of extraneous
; assembler warnings
; <12> 6/21/90 PK Support for balloon help. Map old 3rd party DITLs, which hide
; items with an offset of 1000, to use 16384 so they work with
; Show/HideDItem. Sparing still off.
; <11> 6/16/90 PK Adding changebars.
; <10> 6/16/90 PK Support for disk sparing, conditionally enabled via BBS feature,
; which is set false for now. The new file DiskInitBadBlock.c
; contains the sparing code. Default button handling redone,
; including a UserItem so the highlight is redrawn on update
; events. Added several new DITL items for sparing and balloon
; help (forthcoming). The mechanism used to change the dialog
; upgraded to use ShowDItem, HideDItem, and UpdtDialog.
; <9> 6/11/90 DDG NEEDED FOR SIXPACK: Changing the resource ID of the
; initialization dialog and the formatter back to their old
; values. Also fixed up the last couple of comments so that they
; match the projector information. (PS- Phil, you probably don<6F>t
; want to use real double quotes...use option-[ and option-shift-[
; instead)
; <8> 5/30/90 PK Fix bug when saying <20>Disk init failed! There are open files<65><73>,
; a value was pushed .W and popped .L, screwing up stack.
; <7> 5/22/90 PK ESC->Cancel, take 2
; <6> 5/21/90 PK Map ESC->Cancel in dialogs.
; <5> 5/1/90 DDG Removed the temporary conditionals that I added for Sys605.
; <4> 4/11/90 ngk Renumbeedr DLOG from -6047 to -6079. It was in the PACK 3 range
; instead of PACK 2 range - RezCop... If this becomes a problem
; because some apps have a DLOG in them with that old ID, then
; I'll special case it.
; <3> 3/2/90 DDG Added conditionals for Sys605.
; <2> 1/4/90 dba get rid of equates that are now in SysErr.a and SonyEqu.a; got
; rid of some old leftover code intended to handle the case of a
; Macintosh that does not support HFS
; <1.4> 9/6/89 dba fixed bug in icon positioning code (reported in the Usenet
; digest!)
; <1.3> 4/17/89 CCH Made temporary check from version 1.1 permanent.
; <1.2> 1/31/89 CCH Merged changes from 6.0.3.
; <1.1> 1/3/89 CCH Added TEMPORARY specific check for Sony driver before invoking
; 'Get Format List' driver Status call to avoid problems with 3rd
; party drivers which either die or don't check CSCode values.
; <1.0> 11/16/88 CCH Added to EASE.
; <S547> 7/27/88 JB Added TEMPORARY specific check for Sony driver before invoking
; 'Get Format List' driver Status call to avoid problems with 3rd
; party drivers which either die or don't check CSCode values.
; 2/29/88 GGD (S413) Changed DITL ordering so that the first 20 items are
; exactly the same as they were in System 5.0 Added checks to see
; if new code is running with an older DLOG/DITL, because some
; applications (eg. Disk First Aid) override the resources from
; the system file with their own. And translate new messages into
; the closest old message. Really removed the checks to see if HFS
; exists (mentioned in the Feb 20 change). Fixed old bug in
; re-format, return, or enter would behave like eject, instead of
; the default button, which is Cancel.
; 2/26/88 GGD Added check for ExtFSErr, treated same as NoMacDiskErr. Fixed
; bugs in busy on unmount code, return proper error code, don't
; eject the disk. Re-organized code dealing with ReFormat. Added
; code and dialog message to handle fBsyErr from unmount. Added
; code and dialog message to handle GCRonMFMErr Added temporary
; definition of GCRonMFMErr until it is in SysErr.a Added
; temporary definition of FmtLstCode until it is in SonyEqu.a
; 2/25/88 GGD Changed "Option" Key detection to use equates Added equates for
; volume name sizing, block size GetDriveInfo Reads block 2 to get
; error code, and update driver state used to compute FormatList
; Initialize all locals to zero. WrBlnkDir now calls ClrStkBuf,
; since it depends upon it being zeros before it fills in fields.
; Changed Icon handling to shift Icon Data instead of rectangle
; Changed to check error code for twoSidedErr, instead of trying
; to figure it out from the drive queue info. Changed GetDriveInfo
; to create and return a format list if the driver doesn't support
; it.
; 2/21/88 GGD Removed support for old item lists. Changed version number to 12
; Changed user interface: 1) "Initializing Disk..." is now 3
; messages as follows "Formatting Disk..." "Verifying Format..."
; "Creating Directory..." 2) Ask for volume name before the long
; wait for format/verify 3) High Light Default buttons in dialogs
; 4) Added Extra warning, for non-reFormat badMounts
; 2/20/88 GGD Changed to use _HLock/Unlock,_HPurge/NoPurge,_HGetState/SetState
; Removed 64K ROM, and MacXL support, now assume HFS exists, and
; driver supports format and verify calls. The code in SonyFMTR.a
; and the FMTR -6078 resource in the system file are no longer
; needed. Updated to use equates from SysEqu.a, PackMac.a and
; SonyEqu.a instead of hard coded constants. Fixed assembler
; branch warnings Converted data structure equates to records
; Defined equates for the DITL items
; 2/18/88 GGD Added SuperDrive support (1440K MFM disks). Isolated all driveQ
; accesses and Sony specific code in new routine GetDriveInfo,
; which replaces GetSides
; 8/31/87 JSP Modified to look at error code from UnmountVol call and respond
; with initialization failed if the file is busy.....no
; interesting messages as of yet.
; 8/13/86 DLD Changed the Includes to use new MPW equs.
; 7/31/86 TJ GetSides checks refnum in the drive Q instead of drive number to
; determine sidedness.
; 1/30/86 EHB Check driver version numbers. If > 3 then use driver's
; formatter.
; 1/7/86 EHB Disallow TFS format for 400K volumes if TFS doesn't exist
; System 3.0
; 12/12/85 EHB Fixed bug in TFSFormat
; 12/3/85 EHB Made TFS Format and Sony Init separate modules (resources of
; type FMTR).
; 9/19/85 EHB Commented out check for apple // disks (too flaky)
; 9/16/85 EHB Don't get icon for single sided sonys (MacXL fix)
; 9/16/85 EHB DQDrvSize field used differently by MacXL
; 9/9/85 EHB Check for Apple // disks. No longer check for BadAdrMkErr.
; <fix> 8/25/85 LAK Fixed exit restore of icon handle, item rect (used to use labels
; saveRect and theRect).
; <10> 8/23/85 EHB Added TEDeactivate before laying down directory
; <9> 8/19/85 EHB FSDSIntErr errors are formattable
; <8> 8/15/85 EHB Put up arrow cursor right after NewDialog
; <7> 8/12/85 EHB Put up watch cursor during format, verify make watch unpurgeable
; in DILoad, release in DIUnload Put up cancel button when
; DIBadMount is called for reformat (Err=0)
; 8/8/85 EHB Modified TFSInit for more flexible node structure
; 7/30/85 EHB Use VolNameBuf instead of IOPB for passing volume name
; 7/22/85 EHB Fixed error code return bug
; 7/11/85 EHB Fixed old item list message display
; 7/2/85 EHB FmtBadMount Err=0 now uses old volume name, doesn't prompt.
; 7/2/85 EHB Rearranged logic for checking for disk-switch to good volume
; 7/1/85 EHB Final tweaks of icon save/restore allocate/dispose
; 6/27/85 EHB Enhanced FmtBadMount with Err=0 for reformatting
; 6/26/85 EHB Aligned disk's icon with text on screen Preserve original icon
; so default is correct every time
; 6/25/85 EHB Added cancel button for non-ejectable disks (returns 1 as does
; cancel) Fixed bogus double updates (slow but steady...) Added
; special case for write-protected disks
; 6/24/85 EHB Display disk's icon in dialog box
; 6/23/85 LAK Put in test for double sided disk in single sided drive
; 6/23/85 EHB Erase items as moved, redraw entire dialog at end of
; ChangeDialog.
; 6/21/85 LAK Added code for better drive sizing. Modified for latest TFS
; changes (V 16). Added change for 1-side formatting of
; double-sided disks.
; 6/17/85 EHB Modified to format TFS volumes too.
; 3/6/85 LAK Moved Sony-specific format code to disk driver. All vars are now
; linked off stack. Checked GetResource(DLogID) for success.
; 2/14/85 JTC Make named RSRC.
; 2/2/85 LAK Quick hack...
; 1/14/85 JTC MDS.
; ROM85
; 1/18/84 LAK Added untested fix for filter proc hang on update events . . .
; 1/16/84 LAK Fixed bug: wasn't passing error code if mounted volume on
; format, zero commands . . .
; 1/13/84 LAK Key Sony drive recognition off DCE DCltQueue+1 newly defined
; version number . . . we go after drive numbers 1 and 2 which are
; driven by driver versions 0-3 - others must do their own
; formatting and verifying . . .
; 1/12/84 LAK Fixed bug in filter proc preventing enter, cr key endings.
; 1/10/84 LAK Changed from alerts to dialogs due to continued problems (needs
; new system traps CouldDialog and FreeDialog).
; 1/1/84 LAK Tweaked Enter/Return case making them into a space so that
; non-printable character symbol doesn't flash on screen.
; 12/28/83 LAK Enter and Return now act to confirm name entry after format.
; 12/19/83 LAK Fixed bugs in WrBlnkDir, DoFormat, and FillInMarks.
; 12/14/83 LAK Fixed bug in file directory clear code.
; 12/10/83 LAK Added FmtFormat, FmtVerify, and FmtZero calls. No longer gives
; verify message feedback. Uses a different icon. Verify made to
; work with two-sided drive. This package now checks to make sure
; the unreadable disk has not been swapped out for the alert.
; FmtBadMnt now ejects for errors it does not handle: if it comes
; back with a zero result code, the new disk has been mounted
; (except for NSDrvErr). WrBlnkDir now writes variable format
; depending upon size of volume; the file and master directories
; are zeroed.
; 10/24/83 LAK Started from parts of SonyUtil and SonyFormat.
;
; To Do:
;
; Disk speed is adjusted to within 1% of spec at each speed class boundary.
;
; Notes:
;
; - speed table should already be figured out (since this package is
; only called on mount errors) but we could check . . .
; - we should also be recal'ed already . . .
;
; Six Package calls are supported: 0, 2, 4, 6, 8, 10
;
; (0) FUNCTION FmtBadMnt(where: Point; evtmessage: longint): integer;
;
; (2) PROCEDURE FmtLoad;
;
; (4) PROCEDURE FmtUnLoad;
;
; (6) FUNCTION FmtFormat (drivenum: integer): integer;
;
; (8) FUNCTION FmtVerify (drivenum: integer): integer;
;
; (A) FUNCTION FmtZero (drivenum: integer; volname: str255): integer;
;
; Initialization consists of writing zeroed sectors on the disk, verifying the
; format, and then writing a blank file system directory on the diskette
; with the volume name provided by user input.
;
; To Do:
; - add countdown of tracks (seconds?) as track is formatted ... do this during seek
; - may want to check dskerr in case some other drive problem caused IOErr
; - allow other type formats (large/small directory, allocation block size).
; - check dispatch code for validity. Can<61>t because don<6F>t know what params to strip.
; - don<6F>t assume GetNewDialog succeeds (use new DMgrErr??).
;
; <30> has3rdFloppy is false for both System and ROM builds.
;
if (&type('has3rdFloppy') = 'UNDEFINED') then ; <30>
has3rdFloppy: equ 0 ; <30>
endif ; <30>
STRING ASIS
CASE OBJECT ; so we can interface to C object modules <PK/16Jun90>
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'SonyEqu.a'
INCLUDE 'PackMacs.a'
INCLUDE 'Balloons.a'
PRINT ON
;----------------------------------------------------------------------------------------------------
Pkg2 MAIN EXPORT
IMPORT diBadBlockPass1:CODE ; locate bad blocks after formatting disk <PK/16Jun90>
IMPORT diBadBlockPass2:CODE ; remove bad blocks from free pool <PK/16Jun90>
OldHide EQU 1000 ; old offset used to hide dialog items <PK/21Jun90>
NewHide EQU 16384 ; new offset, as used by ShowDItem/HideDItem <PK/21Jun90>
cmdOptShift EQU $8005 ; command-option-shift key <KST/06Dec90>
DlogID EQU -6079 ; <PK/21Jun90>
TFSCode EQU -6079 ; code to write TFS directories <PK/21Jun90>
ChEnter EQU $03
ChCR EQU $0D
ChESC EQU $1B ; Escape key <PK/22May90>
ChColon EQU $3A
OptKeyCode EQU 58 ; Key Code for option key <GGD/25feb88>
MaxVNameLen EQU 27 ; allow 27 chars max in a volume name <GGD/25feb88>
VNameBufLen EQU 32 ; use a 32 byte buffer to hold the vol name <GGD/25feb88>
BlockSize EQU 512 ; disk blocks are 512 bytes long <GGD/25feb88>
FmtListMax EQU 16 ; max number of formats supported <GGD/25feb88>
; Dialog item list numbers:
; *WARNING*: the ChangeDialog routine herein, and its callers, rely on there being no more
; than 32 visible dialog items. We're out of items, but with a little work you'll be able
; to figure out a way to use item 0.
itIcon EQU 1 ; Icon <GGD/20feb88>
itInitBut EQU 2 ; Initialize button <GGD/20feb88>
itEjectBut EQU 3 ; Eject button <GGD/20feb88>
itOkBut EQU 4 ; OK button for "Please name this disk" screen <PK/16Jun90>
itInitIt EQU 5 ; "Do you want to initialize it?" <GGD/20feb88>
itNameText EQU 6 ; "Untitled" (Edit Text) <GGD/20feb88>
itUnReadable EQU 7 ; "This disk is unreadable:" <GGD/20feb88>
itDamaged EQU 8 ; "This disk is damaged:" <GGD/20feb88>
itNotMacDisk EQU 9 ; "This is not a Macintosh disk:" <GGD/20feb88>
itNameDisk EQU 10 ; "Please name this disk:" <GGD/20feb88>
itFormatting EQU 11 ; "Formatting disk . . ." <GGD/21feb88>
itUndoInitIt EQU 12 ; "" (blank used to remove item 5) <GGD/20feb88>
itInitFailed EQU 13 ; "Initialization failed!" <GGD/20feb88>
itInitThis EQU 14 ; "Initialize this disk?" <GGD/29feb88>
Rev1DITLlen EQU itInitThis ; original DITL just had these messages <GGD/29feb88>
it2SidedDisk EQU 15 ; "This is a two-sided disk!" <GGD/20feb88>
it1SidedBut EQU 16 ; One-sided button <GGD/20feb88>
it2SidedBut EQU 17 ; Two-sided button <GGD/20feb88>
itCancelBut EQU 18 ; Cancel button <GGD/20feb88>
itWrProtected EQU 19 ; "This disk is write-protected." <GGD/20feb88>
itParamText EQU 20 ; "^0" param text for reformat <GGD/20feb88>
Rev2DITLlen EQU itParamText ; then these messages were added <GGD/29feb88>
itVerifying EQU 21 ; "Verifying Format..." <GGD/29feb88>
itCreatingDir EQU 22 ; "Creating Directory..." <GGD/29feb88>
itFilesBusy EQU 23 ; "There are open files on this disk." <GGD/29feb88>
itGCRonMFM EQU 24 ; "GCR format on High Density media" <GGD/29feb88>
itWarnMsg EQU 25 ; "This process will erase all info<66>" <GGD/29feb88>
itWarnCancel EQU 26 ; cancel button for above warning <GGD/29feb88>
itWarnErase EQU 27 ; erase button for above warning <GGD/29feb88>
itWarnIcon EQU 28 ; warning ICON for above warning <GGD/29feb88>
Rev3DITLlen EQU itWarnIcon ; and finally these messages were added <GGD/29feb88>
itReVerifying EQU 29 ; "Reverifying disk<73>" <PK/16Jun90>
itFailedOkBut EQU 30 ; OK button for "Initialization failed!" <PK/16Jun90>
itNewFormat EQU 31 ; "This disk is in a new format..." <PK/24Aug90>
Rev4DITLlen EQU itNewFormat ; *WARNING*: must not be > 31! <PK/27Aug90>
; The following dialog items never need to be passed to ChangeDialog, and therefore can have
; item#s greater than 31.
itUserItem EQU 32 ; UserItem for bold outline of default button <PK/16Jun90>
itHelpMsgs EQU 33 ; the 'hdlg' item, which points to balloon help msgs <PK/16Jun90>
HiLiteButtons EQU (1<<itEjectBut)+\ ; <GGD/21feb88>
(1<<itCancelBut)+\ ; <GGD/21feb88>
(1<<itOkBut)+\ ; <GGD/21feb88>
(1<<itFailedOkBut)+\; <PK/16Jun90>
(1<<itWarnErase) ; <GGD/21feb88>
DiskUtilPkg
BRA.S @0 ; skip around header
DC.W 0 ; flags word
DC.L ('PACK') ; I am a PACK
DC.W dskInit ; whose ID is 2: (dskInit)
DC.W 17 ; version number for sparing <PK/21Jun90>
@0 MOVE.L (SP)+,A0 ; return address
MOVE.W (SP)+,D0 ; offset
BNE.S @1 ; br for packs 2 ,4, 6, 8, 10
MOVEM.L (SP)+,D1-D2 ; pack 0 has 2 longword params
@1 ; 6=diFormat, 8=diVerify, 10=diZero
CMP.W #6,D0 ; pack 6, 8, or 10?
BLT.S @3 ; br if not (0, 2, or 4)
CMP.W #diZero,D0 ; pack 10? <GGD/20feb88>
BNE.S @2 ; br if not
MOVE.L (SP)+,D2 ; pack 10 has volname ptr first
@2 MOVE.W D0,D1 ; save dispatch discriminator
SWAP D1 ; in highword of D1
MOVE.W (SP)+,D1 ; get drive number parameter
MOVEQ #0,D0 ; go to first pack . . .
@3 MOVE.L A0,-(SP) ; put back return address
LEA @5(D0.W),A1 ; index into dispatch table <GGD/20feb88>
MOVE.L A1,D0 ; setup address for StripAddress <GGD/20feb88>
_StripAddress ; clean the address <GGD/20feb88>
MOVEA.L D0,A1 ; save dispatch address <GGD/20feb88>
LEA DiskUtilPkg,A0 ; package pointer
_RecoverHandle
_HGetState ; get handle state <GGD/20feb88>
MOVE.B D0,-(SP) ; save handle state <GGD/20feb88>
_HLock ; make sure we're locked while inside <GGD/20feb88>
MOVE.L A0,-(SP) ; save for common exit
JSR (A1) ; pass A0=pkg handle, D1=event message
MOVE.L (SP)+,A0 ; recover package handle
MOVE.B (SP)+,D0 ; get saved handle state <GGD/20feb88>
_HSetState ; restore handle state <GGD/20feb88>
RTS ; and return
@5 BRA.S SubPack0 ; call package to handle mount error <GGD/20feb88>
BRA.S SubPack2 ; load package
BRA.S SubPack4 ; unload package
;_______________________________________
;
; call to load needed
; resources . . . makes them unpurgeable
;_______________________________________
SubPack2
BCLR #Purge,8(SP) ; tweek saved state of package <11Dec85>
; to make unpurgeable
SUBQ #4,SP ; get the watch
MOVE.W #watchCursor,-(SP) ; push the id <GGD/20feb88>
_GetCursor
MOVE.L (SP)+,A0 ; get the handle
_HNoPurge ; and make it unpurgeable <GGD/20feb88>
MOVE.W #DlogID,-(SP) ; make sure our dialog is in memory
_CouldDialog
BSR.S GetTFSInit ; get TFS init code, if necessary <3Dec85>
_HNoPurge ; and make it unpurgeable <GGD/20feb88>
rts
;---------------------------
GetTFSInit
MOVE.W #TFSCode,D0 ; get id of TFSInit code <3Dec85>
SUBQ #4,SP ; make room for handle <3Dec85>
MOVE.L #'FMTR',-(SP) ; get type 'FMTR' <3Dec85>
MOVE.W D0,-(SP) ; push ID <3Dec85>
_GetResource ; get the resource <3Dec85>
MOVE.L (SP)+,D0 ; test the handle <3Dec85>
MOVE.L D0,A0 ; get into A0 for easy access <3Dec85>
BEQ.S @done ; => no room, just return <3Dec85>
MOVEQ #-1,D0 ; MI if got the resource, good return <3Dec85>
@done
RTS ; EQ if couldn't get it <3Dec85>
;_______________________________________
;
; call to set associated
; resources purgeable
;_______________________________________
SubPack4
BSET #Purge,8(SP) ; tweek state saved on stack <11Dec85>
; to make us purgeable when we exit
SUBQ #4,SP ; get the watch
MOVE.W #watchCursor,-(SP) ; push the id <GGD/20feb88>
_GetCursor
MOVE.L (SP)+,A0 ; get the handle
_HPurge ; and make it purgeable <GGD/20feb88>
MOVE.W #DlogID,-(SP) ; free our dialog in memory
_FreeDialog
BSR.S GetTFSInit ; get TFS init code, if necessary <3Dec85>
_HPurge ; and make it purgeable <GGD/20feb88>
rts
;__________________________________________________________________;
;
; SubPacks 0, 6, 8, and 10
;
; Possible MountVol errors:
; IOErr 'uninitialized?' (Check DskErr?)
; BadMDBErr 'diskette needs scavenging?'
; NoMacDskErr 'not a Mac diskette'
;
; MemFullErr:
; ParamErr
; VolOnLinErr
; ExtFSErr
; NSDrvErr just eject and return
;
; Diskette initialization is provided upon user request for the first three
; errors only: the last 5 will just eject the diskette and return. MemFullErr
; should be intercepted by the default growzone proc for the system heap.
;
; If FmtBadMount is called with an error code = 0, then the user is prompted to
; reformat the volume. The volume is reformatted with its previous name.
;
;__________________________________________________________________;
; on entry D1=event message, D2=point to plot dialog at, 14(SP)=result (SubPack 0)
FmtLocals RECORD 0,DECR ; A6 offsets <GGD/20feb88>
DS.W 1 ; (word) unused for now <PK/21Jun90>
OldPort DS.L 1 ; (long) save port <GGD/20feb88>
DlogResult DS.W 1 ; (word) ModalDialog result <GGD/20feb88>
theRect DS.W 4 ; (rect) item rectangle <GGD/20feb88>
theItem DS.L 1 ; (long) item handle <GGD/20feb88>
theType DS.W 1 ; (word) item type <GGD/20feb88>
itemCount DS.W 1 ; (word) number of items in list, but not > 31 <PK/16Jun90>
saveRect DS.W 4 ; (rect) place to save the old icon's rect <GGD/20feb88>
saveIcon DS.L 1 ; (long) place to save the old icon's handle <GGD/20feb88>
FmtParam DS.W 1 ; (word) $0001 or $0002 depending on sides to format<GGD/20feb88>
DQElPtr DS.L 1 ; (long) drive queue element ptr <GGD/20feb88>
DriveBlks DS.L 1 ; (long) drive size in blocks <GGD/20feb88>
StackBuf DS.B BlockSize ; ( 512) large buffer for volname, disk blk <GGD/25feb88>
VolNameBuf DS.B VNameBufLen ; ( 32) temp buffer for volume name <GGD/25feb88>
IOPBlk DS.B IOVQElSize ; ( 64) parameter blk for I/O calls <GGD/20feb88>
; NOTE: name is read into VolNameBuf, assumes StackBuf is after to catch overflow chars
DiskErrCode DS.W 1 ; (word) Error Code returned from read of block 2 <GGD/25feb88>
FmtListLen DS.W 1 ; (word) Number of 8 byte entries in FormatList <GGD/25feb88>
FormatList DS.B 8*FmtListMax ; list of 8 byte records of allowable fmts <GGD/25feb88>
dftButton DS.W 1 ; (word) default button#, or 0 <PK/16Jun90>
BadBlkHndl DS.L 1 ; (long) handle to bad block list, or NULL <PK/16Jun90>
CheckSum DS.L 1 ; (long) partial chksum of blk 2 to identify disk <PK/06Aug90>
HelpState DS.B 1 ; (byte) true if we have temporarily disabled help <PK/23Aug90>
; WARNING: DiskInitHFS.a shares this stack frame, and uses DQElPtr, DriveBlks <GGD/21feb88>
; StackBuf, VolNameBuf, and IOPBlk. Don't make changes that would <GGD/21feb88>
; cause their offsets to change. <GGD/21feb88>
ALIGN 4 ; make the stack frame a multiple of long words <GGD/21feb88>
FmtLinkSize DS.B 0 ; <GGD/20feb88>
ENDR ; <GGD/20feb88>
; Flag bit numbers for flags stored in D5.L <GGD/18feb88>
bReFormat equ 0 ; re-format request <GGD/18feb88>
bEjectable equ 1 ; disk is ejectable <GGD/18feb88>
bWrProt equ 2 ; Disk is locked (write protected) <GGD/25feb88>
WITH FmtLocals ; use record fields <GGD/20feb88>
SubPack0 LINK A6,#FmtLinkSize
MOVEM.L D3-D5/A2,-(SP) ; preserve registers
BSR ClrLocals ; clear all local variables <GGD/25feb88>
MOVEQ #NSDrvErr,D3 ; assume we can't find it in the drive queue
MOVE.L DrvQHdr+QHead,D0 ; find the drive queue element
@1 BEQ Pkg0Exit ; exit if drive not found in drive queue
MOVE.L D0,A1
CMP.W DQDrive(A1),D1 ; this entry?
BEQ.S @2 ; br if so
MOVE.L QLink(A1),D0
BRA.S @1
@2 MOVE.L A1,DQElPtr(A6) ; save in DQElPtr
MOVE.L DQDrive(A1),IODrvNum+IOPBlk(A6) ; fill in IODrvNum, IORefNum <08 Jul 85>
MOVE.L D1,D3 ; error/drive
SWAP D3 ; check out the drive/error
MOVEQ.L #0,D5 ; clear all flags <GGD/18feb88>
TST.W D3 ; is it a reformat call? <02 Jul 85>
SEQ D5 ; D5.B = $FF if reformat call (used in TestVol) <02 Jul 85>
NEG.B D5 ; $00/$FF -> $00/$01 setup bit 0 (bReFormat) <GGD/18feb88>
BSR.S GetTFSInit ; get TFS init code, if necessary <GGD/25feb88>
_HLock ; lock it down <GGD/20feb88>
CMP.W #diVerify,D3 ; <GGD/20feb88>
BNE.S @6
BSR GetDriveInfo ; get the drive/disk attributes <GGD/18feb88>
BSR FmtVerify ; code 8 means straight verify
BRA GoPkg0Exit ; (it may be a mounted volume)
@6 CMP.W #diFormat,D3 ; <GGD/20feb88>
BNE.S @7 ; => check for zero disk
BSR TestVol ; is volume mounted? <02 Jul 85>
BEQ GoPkg0Exit ; => yes, exit with error in D3 <02 Jul 85>
BSR GetDriveInfo ; get the drive/disk attributes <GGD/18feb88>
BSR Format ; code 6 means straight format
BRA.S GoPkg0Exit
@7 CMP.W #diZero,D3 ; <GGD/20feb88>
BNE CkErrType ; ReFormat <GGD/18feb88>
;; DIZero: need to do disk sparing here.; <KST/08Feb91 #26>
;---------------------------------------------------------------------------------------------
BSR GetDriveInfo ; get the drive/disk attributes <KST/08Feb91 #26>
BSR FmtVerify ; try verifying it <KST/08Feb91 #26>
BEQ.S @wrtBlankDir ; skip if no bad sectors <KST/08Feb91 #26>
;; If verify failed, look for bad blocks !!!! <KST/08Feb91 #26>
BSR WhichFormat ; MFS or HFS? <KST/08Feb91 #26>
BEQ Pkg0Exit ; don't bother sparing if MFS volume <KST/08Feb91 #26>
; D3.W has error code from FmtVerify <KST/08Feb91 #26>
;; disable sparing if 'command-option-shift' key down <KST/08Feb91 #26>
MOVE.W KeyMap+6,D1 ; get keys down <KST/08Feb91 #26>
CMP.W #cmdOptShift,D1 ; test command-option-shift key <KST/08Feb91 #26>
BEQ Pkg0Exit ; don't do sparing <KST/08Feb91 #26>
; D3.W has error code from FmtVerify <KST/08Feb91 #26>
BSR ShowWatch ; no relinquish here <KST/08Feb91 #26>
MOVE.L D2,-(SP) ; save volname ptr <KST/08Feb91 #26>
PEA BadBlkHndl(A6) ; point to place to put Bad block list handle
PEA StackBuf(A6) ; our buffer <KST/08Feb91 #26>
PEA IOPBlk(A6) ; the IO param block <KST/08Feb91 #26>
MOVE.L DriveBlks(A6),-(SP) ; block count <KST/08Feb91 #26>
BSR diBadBlockPass1 ; make a list of bad blocks <KST/08Feb91 #26>
LEA 4*4(SP),SP ; pop off the args <KST/08Feb91 #26>
MOVE.L (SP)+,D2 ; restore D2 <KST/08Feb91 #26>
BSR ShowArrow ; change cursor back to default <KST/08Feb91 #26>
TST.W D0 ; ok? Test return value. <KST/08Feb91 #26>
BNE.S @Fail3 ; disk is unrepairable or drive malfunction
; error code in D0 <KST/08Feb91 #26>
;---------------------------------------------------------------------------------------------
@wrtBlankDir
MOVE.L D2,A0 ; vol name ptr
BSR WrBlnkDir ; code 10 means straight zero disk
BNE.S GoPkg0Exit ; exit on error <KST/08Feb91 #26>
;--------------------------------------------------------------------------------------------
MOVE.L BadBlkHndl(A6),D0 ; did we spare any bad blocks? <KST/08Feb91 #26>
BEQ.S @9 ; no <KST/08Feb91 #26>
MOVE.L D0,-(SP) ; yes, pass handle to bad block list <KST/08Feb91 #26>
PEA IOPBlk(A6) ; the IO param block <KST/08Feb91 #26>
PEA StackBuf(A6) ; the buffer <KST/08Feb91 #26>
BSR diBadBlockPass2 ; remove bad blocks from free list <KST/08Feb91 #26>
LEA 3*4(SP),SP ; pop off the args <KST/08Feb91 #26>
TST.W D0 ; OK? <KST/08Feb91 #26>
BNE.S @Fail3 ; quit if removal failed <KST/08Feb91 #26>
@9 ; no sparing <KST/08Feb91 #26>
;--------------------------------------------------------------------------------------------
LEA IOPBlk(A6),A0 ; always try mounting it here
_MountVol
@Fail3 MOVE.W D0,D3 ; check error (should mount . . .)
BLE.S GoPkg0Exit ; <= 0 is OK <KST/21Feb91 #27>
MOVEQ #firstDskErr,D3 ; else, return driver error code <KST/21Feb91 #27>
GoPkg0Exit BRA ToPkg0Exit ; skip all the dialog stuff
;-------------
; Utility TestVol -- Tests to see if the volume in the specified drive is still
; bad. If it is, or if we are reformatting a volume, then returns BNE. If the
; volume looks good, then we assume it should not be reformatted and exit w/BEQ.
;
; Entry: D5 = Flags <GGD/18feb88>
; Exit: D3 = 2 if volume mounted
TestVol LEA IOPBlk(A6),A0 ; point to the IO parameter block <02 Jul 85>
MOVE.W IODrvNum(A0),-(SP) ; preserve DriveNum <08 Jul 85>
_GetVolInfo ; look for volume info <02 Jul 85>
BNE.S @0 ; don't do FlushVol if GetVolInfo failed <BB/16Sep90>
_FlushVol ; make sure it's flushed <BB/16Sep90>
MOVEQ #0,D0 ; restore GetVolInfo result code <BB/16Sep90>
@0 MOVE.W (SP)+,IODrvNum(A0) ; restore DriveNum <08 Jul 85>
TST.W D0 ; test the result <08 Jul 85>
BNE.S @1 ; => no volume, exit with BNE <02 Jul 85>
BTST.L #bReFormat,D5 ; is it a reformat call? <GGD/18feb88>
BNE.S @1 ; => yes, exit with BNE <02 Jul 85>
MOVEQ #2,D3 ; else result = 2 if volume mounted <02 Jul 85>
MOVEQ #0,D0 ; and set BEQ <02 Jul 85>
@1 RTS ; exit w/BEQ if format to be aborted <02 Jul 85>
;------------ <GGD/18feb88>
; Utility GetDriveInfo -- Returns Drive size, drive attributes, dialog item lists, <GGD/18feb88>
; formating information for the disk to be initialized. This is the only routine <GGD/18feb88>
; that looks at information in the drive queue element, and the only place where <GGD/18feb88>
; disk size is computed, since there are many special cases for the .Sony Driver. <GGD/18feb88>
; <GGD/18feb88>
; outputs are as follows: <GGD/18feb88>
; <GGD/18feb88>
; D5.L - The bWrProt and bEjectable flag bits are set <GGD/25feb88>
; if they apply (assumed zero on entry) <GGD/20feb88>
; <GGD/18feb88>
; FmtParam (word) - 0 if non-Sony driver which doesn't support FormatList call <GGD/18feb88>
; - 0..2 Number of formats if driver does support FormatList call <GGD/18feb88>
; clipped to 2 because user interface only allows upto 2 choices <GGD/18feb88>
; 400K drive would always return 1 (400K only) <GGD/18feb88>
; 800K drive would always return 2 (400K/800K) <GGD/18feb88>
; SuperDrive would return 2 (3 clipped to 2) if low density media <GGD/18feb88>
; SuperDrive would return 1 if HiDensity media (1440K only) <GGD/18feb88>
; - 1 if old Sony driver with only one choice (400K drive) <GGD/18feb88>
; - 2 if old Sony driver with 2 choices (800K drive) <GGD/18feb88>
; <GGD/18feb88>
; DriveBlks (long) - Size (in 512 byte blocks) of the disk currently in the drive <GGD/18feb88>
; <GGD/18feb88>
; D0.L - Bit mask of dialog items to be enabled, based on number of <GGD/18feb88>
; choices, and ejectability. Items are enabled as follows <GGD/18feb88>
; 2 - initialize button, if only one format to choose. <GGD/18feb88>
; 3 - eject button, if disk is ejectable <GGD/18feb88>
; 5 - "Do you want to initialize it?", always set <GGD/18feb88>
; 16 - One Sided button, if more than one format to choose <GGD/18feb88>
; 17 - Two Sided button, if more than one format to choose <GGD/18feb88>
; 18 - Cancel Button, if disk is not ejectable <GGD/18feb88>
; all other bits are cleared <GGD/18feb88>
;
; D1.L - Partial checksum of block 2 if read without error, else error code. <PK/06Aug90>
GetDriveInfo ; <GGD/18feb88>
MOVE.L A0,-(SP) ; Preserve A0 <GGD/18feb88>
LEA IOPBlk(A6),A0 ; point to I/O param block <GGD/18feb88>
; Try to read block 2 of the disk to see what kind of error may have occured <GGD/25feb88>
; and to cause a disk access so that the FormatList call will return accurate info <GGD/25feb88>
LEA StackBuf(A6),A1 ; read data into StackBuf <GGD/25feb88>
MOVE.L A1,IOBuffer(A0) ; setup buffer address <GGD/25feb88>
MOVE.L #1*BlockSize,IOByteCount(A0) ; read 1 block <GGD/25feb88>
MOVE.L #2*BlockSize,IOPosOffset(A0) ; absolute address of block 2 <GGD/25feb88>
MOVE.W #1,IOPosMode(A0) ; position mode 1 (from disk start) <GGD/25feb88>
_Read ; try to read block #2 <GGD/25feb88>
MOVE.W D0,DiskErrCode(A6) ; save the error code <GGD/25feb88>
; if the driver supports the more modern FormatList status call, use it to determine <GGD/18feb88>
; the actual disk size, and number of formats supported <GGD/18feb88>
; But first, check for the Sony driver since 3rd party drivers belly-up <JB/27Jul88>
; if they don't understand the Status call. Someday this will change... <JB/27Jul88>
move.l DQElPtr(A6),a1 ; Get ptr to DQE <JB/27Jul88>
cmp.w #DskRfn,dQRefNum(a1) ; Are we talking to the Sony driver? <JB/27Jul88>
lea FormatList(A6),a1 ; Point to the FormatList <JB/27Jul88>
bne.s @ComputeFmtList ; Not the Sony driver, skip the Status call... <JB/27Jul88>
MOVE.W #FmtLstCode,CSCode(A0) ; request a list of possible formats <GGD/18feb88>
MOVE.W #FmtListMax,CSParam(A0) ; max number of 8 byte list items we can store <GGD/25feb88>
MOVE.L A1,CSParam+2(A0) ; list buffer pointer <GGD/18feb88>
_Status ; make the Format List status call <GGD/18feb88>
BEQ.S @UseFmtList ; use result if no error <GGD/25feb88>
; otherwise, create a format list using the information from the drive queue element <GGD/25feb88>
@ComputeFmtList
CLR.W FmtParam(A6) ; Default Format Kind to zero for now <GGD/18feb88>
MOVEA.L DQElPtr(A6),A0 ; get pointer to drive queue element <GGD/25feb88>
MOVE.L DQDrvSz(A0),D1 ; Vol size in 512-byte blocks (word swapped) <GGD/25feb88>
TST.W qType(A0) ; check for new format DriveQ Element <GGD/25feb88>
BNE.S @SwapSize ; if new format, use all 32 bits <GGD/18feb88>
CLR.W D1 ; only first word is valid in old format <GGD/18feb88>
@SwapSize SWAP D1 ; swap halves to form 32 bit block count <GGD/18feb88>
MOVE.L D1,(A1) ; first long word of list is drive block count <GGD/25feb88>
MOVE.B #$40,4(A1) ; mark current disk has this size <GGD/25feb88>
MOVEQ.L #1,D0 ; indicate that list has just 1 entry <GGD/25feb88>
CMPI.W #DskRfn,dQRefNum(A0) ; check for .Sony DRVR ref number? <GGD/18feb88>
BNE.S @SearchList ; skip special cases if not .Sony Driver <GGD/25feb88>
MOVE.W D0,IOPBlk+CSParam(A6) ; assume single sided drive, only 1 possible format <GGD/25feb88>
MOVE.L #800,(A1) ; single sided size is 800 blocks (400K) <GGD/25feb88>
TST.B dsSides-dsQLink(A0) ; how many sides can the drive handle? <GGD/18feb88>
BPL.S @UseFmtList ; just one, format list is complete <GGD/25feb88>
MOVE.L #1600,8(A1) ; double sided size is 1600 blocks (800K) <GGD/25feb88>
CLR.B 12(A1) ; assume disk is not this format <GGD/25feb88>
ADDQ.W #1,IOPBlk+CSParam(A6) ; list now has two entries <GGD/25feb88>
TST.W D1 ; test twoSidedFmt (high byte of DQDrvSz) <GGD/25feb88>
BPL.S @UseFmtList ; if single sided disk, sides/size done <GGD/25feb88>
MOVE.B #$40,12(A1) ; indicate 800K disk in this drive <GGD/25feb88>
CLR.B 4(A1) ; indicate 400K disk not in this drive <GGD/25feb88>
@UseFmtList MOVE.W IOPBlk+CSParam(A6),D0 ; get the list length <GGD/25feb88>
MOVE.W D0,FmtParam(A6) ; use last entry as default format for now <GGD/18feb88>
BLE.S @ComputeFmtList ; ignore list if empty <GGD/25feb88>
; search the format list for the size of the current disk <GGD/18feb88>
@SearchList MOVE.W D0,FmtListLen(A6) ; save number of entries on list <GGD/25feb88>
@SearchLoop MOVE.L (A1)+,D1 ; get the disk size from the Format List <GGD/18feb88>
BTST.B #6,(A1) ; see if current disk has this format <GGD/18feb88>
BNE.S @FmtLstDone ; exit if it does <GGD/18feb88>
ADDQ.L #4,A1 ; point to next list entry <GGD/18feb88>
SUBQ.W #1,D0 ; decrement loop count <GGD/18feb88>
BGT.S @SearchLoop ; loop through all entries <GGD/18feb88>
@FmtLstDone ; <GGD/25feb88>
MOVE.L D1,DriveBlks(A6) ; return block count in DriveBlks <GGD/18feb88>
MOVEA.L DQElPtr(A6),A1 ; get pointer to drive queue element <GGD/18feb88>
MOVE.W dsWriteProt-dsQLink(A1),D1 ; get Locked and Ejectable flag bytes <GGD/18feb88>
BPL.S @NotLocked ; if not write protected <GGD/18feb88>
BSET.L #bWrProt,D5 ; if locked, set flag bit <GGD/18feb88>
@NotLocked ; <GGD/18feb88>
MOVE.L #(1<<itInitIt)+\ ; if not ejectable, enable Init it? message <GGD/20feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itInitBut)+\ ; initialize button <GGD/20feb88>
(1<<itCancelBut),D0 ; and cancel button <GGD/20feb88>
CMPI.B #8,D1 ; see if disk is ejectable <GGD/18feb88>
BGE.S @NotEjectable ; if not an ejectable disk drive <GGD/18feb88>
BSET.L #bEjectable,D5 ; if ejectable, set flag bit <GGD/18feb88>
MOVEQ.L #(1<<itInitIt)+\ ; if ejectable, enable Init it? message <GGD/20feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itInitBut)+\ ; initialize button <GGD/20feb88>
(1<<itEjectBut),D0 ; and eject button <GGD/20feb88>
@NotEjectable ; <GGD/18feb88>
MOVEQ.L #2,D1 ; max number of formats allowed <GGD/18feb88>
CMP.W FmtParam(A6),D1 ; compare to number we found <GGD/18feb88>
BHI.S @DoCheckSum ; if 0 or 1 format, we are done <PK/06Aug90>
MOVE.W D1,FmtParam(A6) ; set format kind to 2 even if more found <GGD/18feb88>
EORI.L #(1<<it1SidedBut)+\ ; enable 1 sided button <GGD/20feb88>
(1<<it2SidedBut)+\ ; enable 2 sided button <GGD/20feb88>
(1<<itInitBut),D0 ; disable initialize button <GGD/20feb88>
@DoCheckSum ; <PK/06Aug90>
MOVE.W DiskErrCode(A6),D1 ; get status from read of block 2 <PK/06Aug90>
EXT.L D1 ; <PK/06Aug90>
BNE.S @Done ; if can't read, use error code as checksum <PK/06Aug90>
LEA StackBuf(A6),A0 ; point to buffer block 2 was read into <PK/06Aug90>
ADD.L drCrDate(A0),D1 ; include creation date in checksum <PK/06Aug90>
ADD.L drLsMod(A0),D1 ; and last mod date <PK/06Aug90>
ADD.L drVN(A0),D1 ; and first few bytes of volume name <PK/06Aug90>
@Done
MOVEA.L (SP)+,A0 ; Restore A0 <GGD/25feb88>
RTS ; return dialog list, disk size, default fmt, flags <GGD/25feb88>
CkErrType
; 'Preflight' the 'DLOG' resource required by the dialog. If there is still a
; disk-switch in our future it will happen now...Note: this assumes that if the DLOG
; is found, all the other resources needed for the format will later be found (that is,
; if one exists, then they all exist).
SUBQ #4,SP ; room for result
MOVE.L #'DLOG',-(SP) ; was DilogType
MOVE.W #DlogID,-(SP) ; id
_GetResource ; preserves D2
MOVE.L (SP)+,D0 ; get handle
BNE.S @1 ; br if we got it
MOVE.W #ResErr,D3 ; otherwise report the generic error
@0 BSR GetDriveInfo ; get ejectable attribute <GGD/18feb88>
BRA.S EjectExit ; and exit, ejecting the disk <GGD/18feb88>
@1:
; Do a final testVol to see if the specified volume needs formatting.
; This also sets up the default volume name if FmtBadMount called to reformat.
LEA VolNameBuf(A6),A1 ; get a pointer to name buffer <02 Jul 85>
MOVE.L A1,IOPBlk+IOVNPtr(A6) ; and pass in the param block <02 Jul 85>
BSR TestVol ; does the volume still look bad? <GGD/20feb88>
BEQ.S @0 ; => no, exit with error in D3 <02 Jul 85>
; What kind of disk and drive do we have? Also, checksum disk so we can identify it.
BSR GetDriveInfo ; get drive attributes and dialog item list <GGD/18feb88>
MOVE.L D1,CheckSum(A6) ; save checksum of disk we are going to init<PK/06Aug90>
; now, examine the drive, disk, and error to determine the upper message
GetUpperMsg MOVEQ #itUnReadable,D1 ; upper msg = "disk is unreadable" <GGD/20feb88>
CMP.W #FSDSIntErr,D3 ; TFS internal errors are formattable <19 Aug 85>
BEQ.S @10 ; => it is! <19 Aug 85>
CMP.W #IOErr,D3 ; IO errors are formattable
BNE.S @1 ; <24 Jun 85>
@10 CMPI.W #twoSideErr,DiskErrCode(A6) ; two-sided disk in single-sided drive? <GGD/25feb88>
BNE.S @4 ; => nope <GGD/25feb88>
MOVEQ #it2SidedDisk,D1 ; upper msg = "Two-sided diskette Dummy" <GGD/20feb88>
BRA.S FirstDialog ; => so do it <24 Jun 85>
@4 CMPI.W #GCRonMFMErr,DiskErrCode(A6) ; if low den fmt on hi den media? <GGD/26feb88>
BNE.S @5 ; => nope <GGD/26feb88>
MOVEQ #itGCRonMFM,D1 ; msg = "GCR format on High Density media" <GGD/26feb88>
BCLR.L #itInitIt,D0 ; "Initialize it?" is part of above text <GGD/26feb88>
@5 BRA.S FirstDialog ; => so do it <GGD/26feb88>
@1 MOVEQ #itDamaged,D1 ; upper msg = "disk is damaged" <GGD/20feb88>
CMP.W #BadMDBErr,D3
BEQ.S FirstDialog ; => bad MDB error
; Check for as-yet-undefined volume formats, such as the rumored "HFS+",
; and warn that this software is too new to handle the disk. Also, we
; *should* (but do not) check for apple // disks in a very cursory way...
; First 4 bytes of block 2 are in FSTemp4: AB CD EF GH
; IF EF = $06 then assume Pascal
; If A = $F (prodos volume directory ID), then assume ProDOS.
; else just say, "Not a Macintosh disk"
MOVEQ #itNotMacDisk,D1 ; assume "Not a Macintosh disk" <GGD/20feb88>
CMP.W #NoMacDskErr,D3
BEQ.S @2 ; yes
CMP.W #ExtFSErr,D3 ; if not recognized by any file system <GGD/26feb88>
BNE.S @3 ; not a readable disk in unrecognized fmt <PK/24Aug90>
@2 CMP.W #'H+',StackBuf(A6) ; future volume format? <PK/24Aug90>
BNE.S FirstDialog ; no, say "Not a Macintosh disk" <PK/24Aug90>
MOVEQ #itNewFormat,D1 ; yes, say "This disk is in a new format<61>" <PK/24Aug90>
BCLR #itInitIt,D0 ; which overwrites "Do you want to init it?"<PK/24Aug90>
BRA.S FirstDialog ; <PK/24Aug90>
@3 BTST.L #bReFormat,D5 ; is it an explicit reformat call? <GGD/18feb88>
BNE.S ReFormat ; => it is, tweak messages <02 Jul 85>
EjectExit BSR DoEject ; eject if ejectable
ToPkg0Exit BRA Pkg0Exit ; just exit for ParamErr, VolOnLinErr,
; ExtFSErr, NSDrvErr, MemFullErr
GetInfo ; D4.W == item#, A2 == dialog ptr <PK/21Jun90>
MOVE.L A2,-(SP) ; dialog ptr <24 Jun 85>
MOVE.W D4,-(SP) ; item number <PK/21Jun90>
PEA theType(A6) ; var: type <24 Jun 85>
PEA theItem(A6) ; var: itemHandle <24 Jun 85>
PEA theRect(A6) ; var: box rectangle <24 Jun 85>
_GetDItem
RTS
SetInfo ; D4.W == item#, A2 == dialog ptr <PK/21Jun90>
MOVE.L A2,-(SP) ; dialog ptr <26 Jun 85>
MOVE.W D4,-(SP) ; item number <PK/21Jun90>
MOVE.W theType(A6),-(SP) ; type <26 Jun 85>
MOVE.L theItem(A6),-(SP) ; itemHandle <26 Jun 85>
PEA theRect(A6) ; and the rectangle <26 Jun 85>
_SetDItem
RTS
ReFormat AND.B #~((1<<itInitIt)+\ ; nuke "init it?" <GGD/20feb88>
(1<<itEjectBut)),D0 ; and eject button <GGD/20feb88>
BSET #itCancelBut,D0 ; and turn on cancel <GGD/20feb88>
MOVEQ #itParamText,D1 ; turn on param text message <GGD/20feb88>
FirstDialog
BSET D1,D0 ; set upper message
MOVE.L D0,D3 ; save message code in D3
; now allocate the dialog
CLR.L -(SP) ; space for result
MOVE.W #DlogID,-(SP) ; our unique ID
CLR.L -(SP) ; use heap storage
MOVE.L MinusOne,-(SP) ; put it up in front
_GetNewDialog ; draw the window
MOVE.L (SP),A2 ; get new dialog ptr, leave for SetPort
PEA oldPort(A6) ; save oldPort
_GetPort
_SetPort ; and start writing in dialog window
CLR.L saveIcon(A6) ; say that we haven't saved icon yet <01 Jul 85>
BSR ShowArrow ; and force in the arrow cursor <EHB 15Aug85>
; saving the old icon indicates that we have to dispose new handle and restore icon
LEA IOPBlk(A6),A0 ; IODrvNum has been filled in <01 Jul 85>
MOVE.W #iconCC,CSCode(A0) ; disk driver icon command <01 Jul 85>
_Control
BNE.S IconOk ; => error, use default icon <01 Jul 85>
; Try to allocate a new handle for a new icon
MOVE.L #128,D0 ; need 128 bytes for an icon <01 Jul 85>
_NewHandle ,CLEAR ; get a new handle into A0 <GGD/25feb88>
BNE.S IconOK ; => no memory, don't change icon <01 Jul 85>
MOVE.L A0,-(SP) ; save the new handle <16 Jul 85>
MOVE.L #itIcon,D4 ; get id for 'GetInfo' <PK/21Jun90>
BSR.S GetInfo ; get the icon's info <PK/16Jun90>
LEA theItem(A6),A0 ; get the current icon <01 Jul 85>
LEA saveIcon(A6),A1 ; get a place to save it <12 Jul 85>
MOVE.L (A0)+,(A1)+ ; save the icon's handle <12 Jul 85>
MOVE.L (A0)+,(A1)+ ; save the icon's rect too <12 Jul 85>
MOVE.L (A0),(A1)
MOVE.L (SP)+,A0 ; get the new handle back <16 Jul 85>
MOVE.L A0,theItem(A6) ; and save as item's data handle <16 Jul 85>
LEA IOPBlk(A6),A1 ; get the parameter block <01 Jul 85>
MOVE.L CSParam(A1),A1 ; get the pointer to the data <01 Jul 85>
MOVE.L (A0),A0 ; point to the icon <01 Jul 85>
; slide the icon up so that the top lines up with the text
MOVEQ #32-1,D0 ; Icon is 32 longs <GGD/25feb88>
@1 TST.L (A1)+ ; is the line blank <GGD/25feb88>
DBNE d0,@1 ; loop until non-blank line found <GGD/25feb88> <1.4>
BEQ.S @3 ; if totally blank, skip copy <GGD/25feb88>
SUBQ.L #4,A1 ; point back to non-blank line <GGD/25feb88>
@2 MOVE.L (A1)+,(A0)+ ; get a long (little doggie) <01 Jul 85>
DBRA D0,@2 ; until dog-gone <01 Jul 85>
@3 BSR SetInfo ; and set new rect, new item handle <PK/21Jun90>
IconOk MOVE.L items(A2),A0 ; get handle to item list <GGD/21feb88>
MOVE.L (A0),A0 ; get pointer to item list
MOVE.W (A0),D4 ; get number of items-1 <PK/21Jun90>
ADDQ.W #1,D4 ; use true count <PK/21Jun90>
CMP.W #32,D4 ; less than 32? <PK/21Jun90>
BLT.S @1 ; skip if <32 <PK/21Jun90>
MOVE.L #31,D4 ; ChangeDialog can only handle 31 items <PK/21Jun90>
@1 MOVE.W D4,ItemCount(A6) ; save number of items for ChangeDialog <PK/21Jun90>
CMP.W #Rev4DITLlen,D4 ; old DITL? <PK/21Jun90>
BGE.S @3 ; skip if new DITL, using NewHide <PK/21Jun90>
; Old DITLs used an offset of 1000 to hide dialog items, instead of 16384 as used now by
; HideDItem/ShowDItem. In the never-ending quest for eternal compatibility, we will translate
; old 3rd-party DITLs if necessary. Note that another kind of translation of old DITLs also
; occurs in ChangeDialog.
@4 ; D4.W == next item# <PK/21Jun90>
BSR GetInfo ; load theType, theItem, theRect <PK/21Jun90>
MOVE.W theRect+2(A6),D0 ; get Left coord from rectangle <PK/21Jun90>
CMP.W #OldHide,D0 ; hidden using old offset? <PK/21Jun90>
BLT.S @5 ; skip if not <PK/21Jun90>
MOVE.W #NewHide-OldHide,D0 ; its hidden, so get factor to adjust <PK/21Jun90>
ADD.W D0,theRect+2(A6) ; change Left <PK/21Jun90>
ADD.W D0,theRect+6(A6) ; change Right <PK/21Jun90>
BSR SetInfo ; update the dialog item <PK/21Jun90>
@5 SUB.W #1,D4 ; more to go? <PK/21Jun90>
BNE.S @4 ; loop if so <PK/21Jun90>
@3 BSR ChangeDialog ; update dialog according to bitmap in D3
; "completely erase disk named xxx()?"
@2 LEA EjectFP,A0 ; first filter proc does nothing
BSR.S GoDlog ; call ModalDialog
SUBQ.W #itInitBut,D0 ; initialize? <GGD/20feb88>
BEQ.S Fmt2Dialog ; => yes, use current value of FmtParam <GGD/18feb88>
CMP.W #itCancelBut-itInitBut,D0 ; cancel? (18-2) <GGD/20feb88>
BEQ.S CancelIt ; => yes, don't eject
CMP.W #itWrProtected-itInitBut,D0 ; write-protect? (19-2) <GGD/20feb88>
BEQ.S @2 ; => keep looping
CMP.W #it1SidedBut-itInitBut,D0 ; one-sided or two-sided? (16-2) <GGD/20feb88>
BGE.S FmtDialog ; => yes, format it
SUBQ.W #itEjectBut-itInitBut,D0 ; eject? (3) <GGD/20feb88>
BNE.S @2 ; keep looping if not
BTST.L #bReFormat,D5 ; was this a re-format call? <GGD/29feb88>
BNE.S CancelIt ; default was cancel on re-format <GGD/29feb88>
EjectIt BSR.S DoEject ; eject if ejectable <25 Jun 85>
CancelIt MOVEQ #1,D3 ; set return message to 1 for user-eject or cancel
BRA RemoveDlg ; remove dialog and return
; call modal dialog to display dialog, detect button hits, etc...
GoDlog MOVE.L A0,-(SP) ; push filter proc
PEA DlogResult(A6) ; code-sharing routine
_ModalDialog
MOVE.W DlogResult(A6),D0 ; get result
RTS
DoEject BTST.L #bEjectable,D5 ; is it ejectable? <GGD/18feb88>
BEQ.S DontEject ; => no, just exit <GGD/18feb88>
LEA IOPBlk(A6),A0 ; eject the disk <25 Jun 85>
_Eject ; <25 Jun 85>
DontEject RTS ; just return <25 Jun 85>
FmtDialog
BNE.S Fmt2Dialog ; => FmtParam already set up <GGD/18feb88>
SUBQ #1,FmtParam(A6) ; unless "one sided" specifically chosen <GGD/18feb88>
Fmt2Dialog
BTST.L #bWrProt,D5 ; is disk write-protected? <GGD/18feb88>
BNE IsLocked ; => yes <GGD/18feb88>
BTST.L #bReFormat,D5 ; is it a re-format call? <GGD/21feb88>
BEQ.S WarnDialog ; skip unmount if not <GGD/26feb88>
; Unmount the volume only if its a reformat call <GGD/26feb88>
LEA IOPBlk(A6),A0 ; point to the IO parameter block <12 Aug 85>
_UnMountVol ; unmount the volume for reformat <12 Aug 85>
; S256: now check the error and if the file is
; busy, then don't format the beast. <31 Aug 87>
cmp.w #fBsyErr,d0
BNE.S StartFormat ; if not busy, go do the format <GGD/26feb88>
BRA IsBusy ; exit with error <GGD/26feb88>
WarnDialog CMPI.W #Rev3DITLlen,ItemCount(A6) ; See if we have the dialog <GGD/29feb88>
BLT.S WarnOK ; if we don't, we can't give warning <GGD/29feb88>
MOVE.L #(1<<itWarnMsg)+\ ; warning message <GGD/29feb88>
(1<<itWarnCancel)+\ ; cancel button <GGD/21feb88>
(1<<itWarnErase)+\ ; erase button (default) <GGD/21feb88>
(1<<itWarnIcon),D3 ; Warning Icon <GGD/21feb88>
BSR ChangeDialog ; put up the warning <GGD/21feb88>
@1 LEA WarnFP,A0 ; wait for erase button <GGD/21feb88>
BSR.S GoDlog ; call ModalDialog <GGD/21feb88>
CMPI.W #itWarnCancel,D0 ; did the user cancel? <GGD/21feb88>
BEQ.S EjectIt ; eject if user canceled <GGD/21feb88>
CMPI.W #itWarnErase,D0 ; is it erase? <GGD/21feb88>
BNE.S @1 ; keep looping if not <GGD/21feb88>
WarnOK ; <GGD/21feb88>
NameDialog MOVE.L #(1<<itOkBut)+\ ; <GGD/26feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itNameText)+\ ; <GGD/20feb88>
(1<<itNameDisk),D3 ; ask user to name diskette <GGD/20feb88>
BSR ChangeDialog
MOVE.L A2,-(SP) ; and select current text
MOVE.W #itNameText,-(SP) ; <GGD/20feb88>
CLR.W -(SP) ; startsel
MOVE.W #100,-(SP) ; endsel
_SelIText
@1 LEA OKFP,A0 ; strip colons, etc.
BSR GoDlog ; call ModalDialog <GGD/29feb88>
SUBQ.W #itOkBut,D0 ; ok? <GGD/21feb88>
BNE.S @1 ; loop until ok
MOVE.L #itNameText,D4 ; get item# for 'GetInfo' <PK/21Jun90>
BSR GetInfo ; get theType, theItem, theRect <PK/16Jun90>
MOVE.L theItem(A6),-(SP)
PEA VolNameBuf(A6) ; read name name buf (o'flo into stackbuffer)
_GetIText ; get the text
MOVE.L tehandle(A2),-(SP) ; push handle to teRecord <EHB 23 Aug 85>
_TEDeactivate ; and turn off that blinking cursor <EHB 23 Aug 85>
StartFormat MOVE.L #(1<<itFormatting)+\; "Formatting Disk..." <GGD/26feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itUndoInitIt),D3; "" <GGD/21feb88>
BSR ChangeDialog ; set up appropriate fields
BSR RemoveBalloons ; disable balloons while formatting <PK/23Aug90>
; Even though we may have preflighted resources with a _CouldDialog etc, it <PK/06Aug90>
; is still possible that mouse clicks outside of the dialog box or the help <PK/06Aug90>
; menu item have caused a disk switch if we were booted from a floppy. If <PK/06Aug90>
; so, we're about to init the boot disk (!), so we make *ONE LAST CHECK*. <PK/06Aug90>
MOVE.W FmtParam(A6),-(SP) ; save 1/2-sided decision across call <PK/28Aug90>
BSR GetDriveInfo ; recompute the checksum <PK/06Aug90>
MOVE.W (SP)+,FmtParam(A6) ; restore decision <PK/28Aug90>
CMP.L CheckSum(A6),D1 ; same disk? <PK/06Aug90>
BNE FmtFail ; if last minute disk switch, abort <PK/06Aug90>
BSR Format ; then try formatting it
BNE FmtFail ; <PK/16Jun90>
MOVE.L #(1<<itVerifying)+\ ; "Verifying Format..." <GGD/21feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itUndoInitIt),D3; "" <GGD/21feb88>
BSR ChangeDialog ; set up appropriate fields
BSR FmtVerify ; try verifying it
;---------------------------------------------------------------------------------------------
; If verify failed, look for bad blocks <PK/16Jun90>
BEQ.S @1 ; skip if no bad sectors <PK/16Jun90>
BSR WhichFormat ; MFS or HFS? <PK/16Jun90>
BEQ FmtFail ; don't bother sparing if MFS volume <PK/16Jun90>
; D3.W has error code from FmtVerify
;; disable sparing if 'command-option-shift' key down <KST/06Dec90>
MOVE.W KeyMap+6,D1 ; get keys down <KST/06Dec90>
CMP.W #cmdOptShift,D1 ; test command-option-shift key <KST/06Dec90>
BEQ FmtFail ; don't do sparing <KST/06Dec90>
; D3.W has error code from FmtVerify
MOVE.L #(1<<itReVerifying)+\ ; "Reverifying Format..." <PK/16Jun90>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itUndoInitIt),D3; <PK/16Jun90>
BSR ChangeDialog ; set up appropriate fields <PK/16Jun90>
BSR ShowWatch ; no relinquish here <PK/21Jun90>
PEA BadBlkHndl(A6) ; point to place to put Bad block list handle
PEA StackBuf(A6) ; our buffer <PK/16Jun90>
PEA IOPBlk(A6) ; the IO param block <PK/16Jun90>
MOVE.L DriveBlks(A6),-(SP) ; block count <PK/16Jun90>
BSR diBadBlockPass1 ; make a list of bad blocks <PK/16Jun90>
LEA 4*4(SP),SP ; pop off the args <PK/16Jun90>
BSR ShowArrow ; change cursor back to default <PK/21Jun90>
MOVE.W D0,D3 ; ok? FmtFail expects error code in D3 <KSCT/25Jan91>
BLE.S @negorzero ; <= 0 is OK <KST/21Feb91 #27>
MOVEQ #firstDskErr,D3 ; else, return driver error code <KST/21Feb91 #27>
@negorzero
BNE FmtFail ; already negative <KSCT/25Jan91>
@1 ; <PK/16Jun90>
;--------------------------------------------------------------------------------------------
MOVE.L #(1<<itCreatingDir)+\ ; "Creating Directory..." <PK/16Jun90>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itUndoInitIt),D3 ; "" <GGD/21feb88>
BSR ChangeDialog ; set up appropriate fields
LEA VolNameBuf(A6),A0 ; point to the name buffer <02 Jul 85>
BSR WrBlnkDir ; lay down a blank directory . . .
BNE FmtFail ; something's wrong <KSCT/08Feb91 #25>
;--------------------------------------------------------------------------------------------
MOVE.L BadBlkHndl(A6),D0 ; did we spare any bad blocks? <PK/16Jun90>
BEQ.S @2 ; no <PK/16Jun90>
MOVE.L D0,-(SP) ; yes, pass handle to bad block list <PK/16Jun90>
PEA IOPBlk(A6) ; the IO param block <PK/16Jun90>
PEA StackBuf(A6) ; the buffer <PK/16Jun90>
BSR diBadBlockPass2 ; remove bad blocks from free list <PK/16Jun90>
LEA 3*4(SP),SP ; pop off the args <PK/16Jun90>
MOVE.W D0,D3 ; OK? <KSCT/08Feb91 #24>
BNE.S FmtFail ; quit if removal failed <PK/16Jun90>
@2 ; <PK/16Jun90>
;--------------------------------------------------------------------------------------------
LEA IOPBlk(A6),A0
_MountVol ; now mount it before we exit . . .
MOVE.W D0,D3 ; check error (should mount . . .)
; *** need to check error here too?
RemoveDlg TST.L saveIcon(A6) ; did we save original icon? <01 Jul 85>
BEQ.S @1 ; => no, no need to restore <01 Jul 85>
MOVE.L #itIcon,D4 ; get item# for icon <PK/21Jun90>
BSR GetInfo ; get theType, theItem, and theRect <PK/21Jun90>
MOVE.L theItem(A6),A0 ; get the new icon's handle <01 Jul 85>
_DisposHandle ; and dispose of it <01 Jul 85>
LEA theItem(A6),A1 ; point to the info block <25 Aug 85>
LEA saveIcon(A6),A0 ; and get the original data <25 Aug 85>
MOVE.L (A0)+,(A1)+ ; restore original data <01 Jul 85>
MOVE.L (A0)+,(A1)+
MOVE.L (A0)+,(A1)+ ; save the icon's handle too <01 Jul 85>
BSR SetInfo ; and save it back to the icon <PK/16Jun90>
@1
MOVE.L A2,-(SP)
_DisposDialog
MOVE.L oldPort(A6),-(SP)
_SetPort ; restore old port
Pkg0Exit ; D3 = error code
BSR GetTFSInit ; get TFS init code, if necessary <3Dec85>
_HUnlock ; unlock it <GGD/20feb88>
_HPurge ; make it purgeable <GGD/20feb88>
BSR RestoreBalloons ; re-enable if necessary <PK/23Aug90>
MOVE.W D3,D0
MOVEM.L (SP)+,D3-D5/A2
UNLK A6 ; clean up stack space . . .
MOVE.W D0,14(SP) ; return result to caller . . . <11Dec85>
RTS
IsLocked MOVE.W #wPrErr,D3 ; say it's write protected
MOVE.L D3,-(SP) ; preserve error message
MOVE.L #(1<<itInitFailed)+\; "Initialization Failed!" <GGD/20feb88>
(1<<itWrProtected)+\; "this disk is write-protected" <GGD/20feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itFailedOkBut),D3 ;the special "OK" button <PK/16Jun90>
BRA.S Fmt2Fail ; => branch around other message
IsBusy MOVE.L D0,-(SP) ; preserve error code <PK/30May90>
MOVE.L #(1<<itInitFailed)+\; "Initialization Failed!" <GGD/26feb88>
(1<<itFilesBusy)+\ ; "There are open files on this disk." <GGD/26feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itFailedOkBut),D3 ;the special "OK" button <PK/16Jun90>
BRA.S FailDialog ; display the message (but don't eject) <GGD/26feb88>
FmtFail MOVE.L D3,-(SP) ; preserve error message
MOVE.L #(1<<itInitFailed)+\; "Initialization Failed!" <GGD/20feb88>
(1<<itIcon)+\ ; the disk icon <PK/16Jun90>
(1<<itUndoInitIt)+\ ; "" <GGD/20feb88>
(1<<itFailedOkBut),D3 ;the special "OK" button <PK/16Jun90>
Fmt2Fail BSR DoEject ; eject if it's ejectable
FailDialog BSR ChangeDialog ; <GGD/29feb88>
@1 BSR RestoreBalloons ; re-enable if necessary <PK/23Aug90>
LEA OKFP,A0 ; wait for OK button press
BSR GoDlog ; call ModalDialog
CMP.W #itFailedOkBut,D0 ; the special OK? <PK/16Jun90>
BEQ.S @2 ; quit loop if so <PK/16Jun90>
SUBQ.W #itOkBut,D0 ; CR, Escape, Enter will map to this button
BNE.S @1 ; loop until ok
@2 MOVE.L (SP)+,D3 ; restore error code
BRA.S RemoveDlg
WarnFP MOVEQ #itWarnErase,D0 ; return Erase item on CR, Enter <GGD/21feb88>
BRA.S MyFilter ; <GGD/21feb88>
EjectFP MOVEQ #itEjectBut,D0 ; return Eject item on CR, Enter <GGD/20feb88>
BRA.S MyFilter
OKFP MOVEQ #itOkBut,D0 ; filter colons, control keys out, <GGD/20feb88>
; return OK item on CR, Enter
MyFilter
MOVEM.L (SP)+,D1-D2/A0-A1 ; D1-return; D2-item var
; A0-event add; A1-dialog add
MOVE.L D1,A1 ; get return address
CLR (SP) ; assume failure return
CMP #KeyDwnEvt,EvtNum(A0) ; See if key event type <PK/21Jun90>
BNE.S FPExit
MOVE.B EvtMessage+3(A0),D1 ; get Ascii
CMP.B #ChColon,D1 ; colon?
BNE.S @1 ; we don't allow colons in a disk name
CLR.W EvtNum(A0) ; so turn it into a null event
@1 CMP.B #CHEnter,D1 ; Enter key?
BEQ.S @2 ; yahoo if enter
CMP.B #CHCR,D1 ; CR key?
BEQ.S @2 ; use default if CR
CMP.B #ChESC,D1 ; escape key? <PK/22May90>
BNE.S FPExit ; exit if not escape, enter or return <PK/22May90>
CMP.W #itWarnErase,D0 ; escape of "will erase all info" warning? <PK/22May90>
BNE.S @2 ; no, map escape->Eject/Cancel <PK/22May90>
MOVEQ #itWarnCancel,D0 ; escape of warning maps to "Cancel" <PK/22May90>
@2
MOVE.L D2,A0 ; point to item result
MOVE.W D0,(A0) ; return appropriate button item
ADDQ.B #1,(SP) ; turn false into true
FPExit JMP (A1) ; return
;_______________________________________________________________________
;
; Routine: ChangeDialog
; Arguments: D3.L (in) -- bit map of Dialog items which should be
; in view . . . bit 1 corresponds to item 1
; A2.L (in) -- dialog pointer
; Function: This routine is used to change the face of our Dialog
; to allow for different strings and buttons at different
; stages of the Dialog. ItemCount is 14 if old DITL; 20 if new.
;
; Since items overlap, we must make 2 passes through the items, one to
; hide those that need it, and the second to show the visible ones.
;_______________________________________________________________________
TranslateTable ; <GGD/29feb88>
; table to translate Rev4 dialogs to Rev3 ; <PK/16Jun90>
dc.b itReVerifying,itVerifying ; <PK/16Jun90>
dc.b itFailedOkBut,itOkBut ; <PK/16Jun90>
dc.b itNewFormat,itNotMacDisk ; <PK/24Aug90>
dc.b 0 ; <PK/16Jun90>
; table to translate Rev3 dialogs into Rev2 ; <GGD/29feb88>
dc.b itVerifying,itFormatting ; <GGD/29feb88>
dc.b itCreatingDir,itFormatting ; <GGD/29feb88>
dc.b itFilesBusy,itUndoInitIt ; <GGD/29feb88>
dc.b itGCRonMFM,it2SidedDisk ; <GGD/29feb88>
dc.b 0 ; <GGD/29feb88>
; table to translate Rev2 dialogs into Rev1 ; <GGD/29feb88>
dc.b it2SidedDisk,itInitIt ; <GGD/29feb88>
dc.b it1SidedBut,itInitBut ; <GGD/29feb88>
dc.b it2SidedBut,itInitBut ; <GGD/29feb88>
dc.b itCancelBut,itEjectBut ; <GGD/29feb88>
dc.b itWrProtected,itUndoInitIt ; <GGD/29feb88>
dc.b itParamText,itInitThis ; <GGD/29feb88>
dc.b itDamaged,itUnReadable ; <GGD/29feb88>
dc.b itNotMacDisk,itUnReadable ; <GGD/29feb88>
dc.b 0 ; <GGD/29feb88>
ALIGN
TranslateDITL ; <GGD/29feb88>
MOVE.B (A0)+,D0 ; get the newer item number <GGD/29feb88>
BEQ.S @exit ; exit when end of list <GGD/29feb88>
MOVE.B (A0)+,D1 ; get the older item number <GGD/29feb88>
BCLR.L D0,D3 ; test and clear the new item <GGD/29feb88>
BEQ.S TranslateDITL ; if already clear, go to next item <GGD/29feb88>
BSET.L D1,D3 ; otherwise, translate into older item <GGD/29feb88>
BRA.S TranslateDITL ; go on to next item <GGD/29feb88>
@exit RTS ; all done <GGD/29feb88>
ChangeDialog
MOVE.L D5,-(SP) ; save D5 <GGD/29feb88>
MOVE.L #HiLiteButtons,D5 ; get bit vector of default buttons <GGD/29feb88>
MOVE.W dftButton(A6),D4 ; is there a default button already? <PK/16Jun90>
BEQ.S @1 ; skip if not <PK/16Jun90>
MOVE.L #0,D0 ; yes, set flag to say "disable it" <PK/16Jun90>
BSR.S DefaultButton ; do so <PK/16Jun90>
@1 MOVE.W ItemCount(A6),D4 ; get item count out of stack frame <PK/16Jun90>
LEA TranslateTable,A0 ; point to the translation table <GGD/29feb88>
CMP.W #Rev4DITLlen,D4 ; is DITL the latest version? <PK/16Jun90>
BGE.S ChgLoop1 ; skip if so <PK/16Jun90>
BSR.S TranslateDITL ; if not, translate into rev3 msgs <PK/16Jun90>
CMPI.W #Rev3DITLlen,D4 ; see if we have enough items for rev3 <GGD/29feb88>
BGE.S ChgLoop1 ; if we do, just display it <GGD/29feb88>
BSR.S TranslateDITL ; if not, translate it into rev2 msgs <GGD/29feb88>
MOVEQ.L #0,D5 ; and don't frame the default buttons <GGD/29feb88>
CMPI.W #Rev2DITLlen,D4 ; see if we have enough items for rev2 <GGD/29feb88>
BGE.S ChgLoop1 ; if we do, just display it <PK/16Jun90>
BSR.S TranslateDITL ; if not, translate it into rev1 msgs <GGD/29feb88>
ChgLoop1 BTST D4,D3 ; is this item to be displayed? <PK/16Jun90>
BNE.S @1 ; skip if so <PK/16Jun90>
MOVE.L A2,-(SP) ; dialog ptr <PK/16Jun90>
MOVE.W D4,-(SP) ; item number <PK/16Jun90>
_HideDItem ; no, so hide dialog item <PK/16Jun90>
@1 SUB.W #1,D4 ; more to go? <PK/16Jun90>
BNE.S ChgLoop1 ; loop if so <PK/16Jun90>
MOVE.W ItemCount(A6),D4 ; reload item count, for 2nd pass <PK/16Jun90>
ChgLoop2 BTST D4,D3 ; is this item to be displayed? <PK/16Jun90>
BEQ.S @1 ; no <PK/16Jun90>
MOVE.L A2,-(SP) ; dialog ptr <PK/16Jun90>
MOVE.W D4,-(SP) ; item number <PK/16Jun90>
_ShowDItem ; yes, display it <PK/16Jun90>
BTST D4,D5 ; is this a default button? <PK/16Jun90>
BEQ.S @1 ; skip if not <PK/16Jun90>
MOVE.L #1,D0 ; flag "enable button" function <PK/16Jun90>
BSR.S DefaultButton ; do it <PK/16Jun90>
@1 SUB.W #1,D4 ; more to go? <PK/16Jun90>
BNE.S ChgLoop2 ; loop if so <PK/16Jun90>
MOVE.L A2,-(SP) ; the window/dialog ptr <PK/16Jun90>
_BeginUpdate ; <PK/16Jun90>
MOVE.L A2,-(SP) ; push the dialog pointer <PK/16Jun90>
MOVE.L visRgn(A2),-(SP) ; update against the visible region <PK/16Jun90>
_UpdtDialog ; <PK/16Jun90>
MOVE.L A2,-(SP) ; the window/dialog ptr <PK/16Jun90>
_EndUpdate ; <PK/16Jun90>
MOVE.L (SP)+,D5 ; restore D5 <GGD/29feb88>
RTS
;-----------------------------------------------------------------------
; Routine: DefaultButton
; Args: D0.W (input) -- 0 to disable, 1 to enable
; D4.W (input) -- item number for default button
; A2 (input) -- dialog ptr
; Function: Draw or erase the bold frame around the default button.
;-----------------------------------------------------------------------
DefaultButton
MOVE.W D0,-(SP) ; save on/off flag <PK/16Jun90>
BSR GetInfo ; load theType, theItem, theRect <PK/16Jun90>
PEA theRect(A6) ; point to rectangle <PK/16Jun90>
MOVE.L #$FFFCFFFC,-(SP) ; (-4,-4) to make bigger <PK/16Jun90>
_InsetRect ; adjust dimensions <PK/16Jun90>
TST.W (SP)+ ; test and pop the on/off flag <PK/16Jun90>
PEA theRect(A6) ; for _EraseRect or _FrameRoundRect <PK/16Jun90>
BNE.S @1 ; skip if enabling button <PK/16Jun90>
_EraseRect ; erase rect if disabling button <PK/16Jun90>
CLR.W dftButton(A6) ; no dft button enabled now <PK/16Jun90>
CLR.L theRect(A6) ; set useritem rectangle to 0... <PK/16Jun90>
CLR.L theRect+4(A6) ; ...so we don't redraw in 'MyItem' <PK/16Jun90>
BRA.S @2
@1 MOVE.L #$00030003,-(SP) ; (3,3) <GGD/21feb88>
_PenSize ; set pen size for outlining buttons <GGD/21feb88>
MOVE.L #$00100010,-(SP) ; (16,16) <PK/16Jun90>
_FrameRoundRect ; draw the dark border <PK/16Jun90>
MOVE.W D4,dftButton(A6) ; remember we have a dft button <PK/16Jun90>
; Set DITL user item up to properly update button, for example after
; balloon help. Note that if our DITL has no UserItem, calling
; SetDItem has no effect. "theRect" has the rectangle to draw, or 0.
; Why bother hand-drawing the bold buttons when we have a UserItem?
; Its so we can remain compatible with old DITLs wo UserItems.
@2 LEA MyItem,A0 ; this is out useritem procedure <PK/16Jun90>
MOVE.L A0,theItem(A6) ; set up <PK/16Jun90>
MOVE.W #userItem+itemDisable,theType(A6) ; <PK/16Jun90>
MOVE.L D4,-(SP) ; save button# <PK/21Jun90>
MOVE.L #itUserItem,D4 ; the item# for useritem proc <PK/21Jun90>
BSR SetInfo ; reframe the button redrawer <PK/21Jun90>
MOVE.L (SP)+,D4 ; restore default button# <PK/21Jun90>
RTS ; <PK/16Jun90>
; UserItem proc to redraw the frame around the default button
; PROCEDURE MyItem(theWindow: WindowPtr; itemNo: INTEGER);
MyItem ; <PK/16Jun90>
MOVE.L 6(SP),A1 ; get ptr to window (also dialog ptr) <PK/16Jun90>
MOVE.W 4(SP),D1 ; get our item# <PK/16Jun90>
SUB.W #16,SP ; save room for our var args <PK/16Jun90>
MOVE.L SP,A0 ; copy ptr to them <PK/16Jun90>
MOVE.L A1,-(SP) ; point to dialog <PK/16Jun90>
MOVE.W D1,-(SP) ; item# <PK/16Jun90>
PEA (A0) ; var: type (ignored) <PK/16Jun90>
PEA (A0) ; var: item (ignored) <PK/16Jun90>
PEA 4(A0) ; var: display rectangle (what we want) <PK/16Jun90>
_GetDItem ; get our display rectangle <PK/16Jun90>
MOVE.L #$00030003,-(SP) ; (3,3) <PK/16Jun90>
_PenSize ; set pen size for outlining buttons <PK/16Jun90>
LEA 4(SP),A0 ; point to rectangle <PK/16Jun90>
PEA (A0) ; <PK/16Jun90>
MOVE.L #$00100010,-(SP) ; (16,16) <PK/16Jun90>
_FrameRoundRect ; draw the dark border <PK/16Jun90>
ADD.W #16,SP ; pop off var arg storage <PK/16Jun90>
MOVE.L (SP)+,A0 ; pop off return address <PK/16Jun90>
ADD.W #6,SP ; pop off our parameters <PK/16Jun90>
JMP (A0) ; back to dialog mgr <PK/16Jun90>
;_______________________________________________________________________
;
; Routine: Format
; Arguments: D0.W (output) -- result code (0 if correctly formatted)
; Function:
;
;_______________________________________________________________________
Format MOVEQ #formatCC,D0 ; <GGD/20feb88>
FV BSR.S ShowWatch
LEA IOPBlk(A6),A0 ; IODrvNum already set up
MOVE.W D0,CSCode(A0) ; disk driver format command
MOVE.W FmtParam(A6),CSParam(A0) ; $0002 to format 2-sided <GGD/18feb88>
_Control
BSR.S ShowArrow ; show arrow cursor, D0 perserved
MOVE.W D0,D3 ; get result
RTS
;_______________________________________________________________________
;
; Routine: FmtVerify
; Arguments: D0.W (output) -- result code (0 if correctly formatted)
; Function: This routine reads all sectors on the newly formatted
; diskette to verify correct format.
;_______________________________________________________________________
FmtVerify MOVEQ #verifyCC,D0 ; <GGD/20feb88>
BRA.S FV
;_______________________________________________________________________
;
; ShowWatch and ShowArrow: Cursor Juggling Routines
; No registers folded, spindled, or mutilated.
;_______________________________________________________________________
ShowWatch MOVEM.L D0-D2/A0-A1,-(SP) ; preserve all registers <EHB 12Aug85>
SUBQ #4,SP ; get the watch <EHB 12Aug85>
MOVE.W #watchCursor,-(SP) ; push the id <GGD/20feb88>
_GetCursor
MOVE.L (SP)+,A0 ; get the handle <EHB 12Aug85>
MOVE.L (A0),-(SP) ; push the data <EHB 12Aug85>
ShowExit _SetCursor ; and make the watch the cursor <EHB 12Aug85>
MOVEM.L (SP)+,D0-D2/A0-A1 ; restore the little registers <EHB 12Aug85>
RTS
ShowArrow MOVEM.L D0-D2/A0-A1,-(SP) ; preserve all registers <EHB 12Aug85>
MOVE.L (A5),A0 ; get pointer to QD globals <EHB 12Aug85>
PEA Arrow(A0) ; get pointer to arrow data <EHB 12Aug85>
BRA.S ShowExit ; make it the cursor, exit <EHB 12Aug85>
;_______________________________________________________________________
;
; ClrStkBuf (Clear Buffer) subroutine
; ClrLocals (Clear all locals) subroutine
;_______________________________________________________________________
ClrLocals MOVEM.L D0/A0,-(SP) ; <GGD/25feb88>
LEA FmtLinkSize(A6),A0 ; get address of stack frame <GGD/25feb88>
MOVE.W #-(FmtLinkSize/4)-1,D0 ; get number of longs (multiple of 4) <GGD/25feb88>
BRA.S ClrBuf ; use common code
ClrStkBuf MOVEM.L D0/A0,-(SP) ; save regs
LEA StackBuf(A6),A0 ; get address
MOVEQ #(BlockSize/4)-1,D0 ; get number of longs <GGD/25feb88>
ClrBuf CLR.L (A0)+ ;
DBRA D0,ClrBuf
MOVEM.L (SP)+,D0/A0 ; restore regs
RTS
ClrVolNameBuf ; <21Jun85>
MOVEM.L D0/A0,-(SP) ; save regs <21Jun85>
LEA VolNameBuf(A6),A0 ; get address <21Jun85>
MOVEQ #(VNameBufLen/4)-1,D0 ; get number of longs <GGD/25feb88>
BRA.S ClrBuf
;_______________________________________________________________________
;
; Routine: WrBlnkDir
; Arguments: (input) A0.L -- ptr to volume name for new disk
; (output) D3.W -- return error in D3. <KST/07Jan91>
; Function: This routine writes a blank master directory on the diskette
; in the specified drive. The file directory is zeroed.
;
; 16x12 = 192 000-191 (94 alloc blks) 002-095 (6 per track, 4 on tk0)
; 16x11 = 176 192-367 (88 alloc blks) 096-183
; 16x10 = 160 368-527 (80 alloc blks) 184-263 (5 per track)
; 16x9 = 144 528-671 (72 alloc blks) 264-335
; 16x8 = 128 672-799 (64 alloc blks) 336-399 (4 per track)
;
; DS = disk size in 512-byte blocks (given)
;
; ABBS = allocation blk blk size = (DS/512 + 1)
; AB = allocation blks = (DS-BBS-MDB-MDB-FDB)/ABBS = DS-6-FDB/ABBS
; MDB = master directory blks = 2 (always - keep this constant by varying ABBS)
; FDB = file directory blocks = DS/64 (small) -or- DS/32 (large), FDB even
; BBS = boot block size = 2
; DSB = dir start block = 2 + MDB = 4
; CS = clump size = 8 * ABS
; ASB = allocation start blk = DSB + FDB = FDB + 4
; ABS = allocation block size = ABBS * 512
;
; .Byte $D2,$D7 ; blank file directory
; .Long 0,0 ; creation date, backup date
; .Word 0 ; volume attributes
; .Word 0 ; number of files
;
; .Word $0004 ; directory start block (always)
; .Word FDB ; length of directory in 512-byte blks
; .Word AB ; total number of allocation blocks
; .Long ABS ; allocation block size
; .Long CS ; clump size
; .Word ASB ; allocation block start
; .Long $00000001 ; next free file number
; .Word AB ; number of free allocation blocks
;_______________________________________________________________________
DefltName DC.B 3
DC.B '???' ; international no gottum VolName symbol
ALIGN 2
WrBlnkDir
; get drive info to get current DriveBlks, which may be different now that <GGD/18feb88>
; format has been called. (eg. 400K before, 800K now) <GGD/18feb88>
BSR GetDriveInfo ; get the drive/disk attributes <GGD/18feb88>
; First do the stuff that both file systems do..
MOVEM.L D1-D7/A0-A4,-(SP) ; save registers other than D0
BSR.S ShowWatch ; show the watch cursor
BSR.S ClrStkBuf ; clear the stack buffer <GGD/25feb88>
LEA StackBuf(A6),A3 ; get stackbuf in A3 for general use
LEA TagData+2,A1 ; point the tag data
CLR.L (A1)+
CLR.L (A1)+ ; zero out the tag data
CLR.L (A1)+
MOVE.L A0,D0 ; name ptr nil?
BEQ.S @0 ; br if so (use default)
TST.B (A0) ; name length zero?
BNE.S @1 ; use default if so
@0 LEA DefltName,A0 ; point to default name = '???'
@1 LEA DrVN(A3),A1 ; point to volume name field in MDB
MOVE.B (A0)+,D0 ; get name length
CMP.B #MaxVNameLen,D0 ; 27-byte name max <GGD/25feb88>
BLS.S @2
MOVE.B #MaxVNameLen,D0 ; truncate it <GGD/25feb88>
@2 MOVE.B D0,(A1)+ ; set name length
@3 MOVE.B (A0)+,D1 ; get next character
CMP.B #ChColon,D1 ; colon?
BNE.S @4 ; skip if not
MOVE.B #' ',D1 ; replace with a space if so
@4 MOVE.B D1,(A1)+ ; transfer the name
SUBQ.B #1,D0
BNE.S @3
BSR.S ClrVolNameBuf ; clear the name buffer <21Jun85>
LEA DrVN(A3),A0 ; source <21Jun85>
LEA VolNameBuf(A6),A1 ; dest <21Jun85>
MOVEQ #VNameBufLen,D0 ; save the name for TFS CNode naming <GGD/25feb88>
_BlockMove ; and move the name <21Jun85>
BSR WhichFormat ; MFS or HFS? <PK/16Jun90>
BNE.S DoTFS ; use HFS (aka TFS) format <PK/16Jun90>
BSR.S MFSInit ; write an MFS directory <GGD/18feb88>
BRA.S DoneInit ; and return error code in D0
DoTFS
BSR GetTFSInit ; is the code available? <3Dec85>
BEQ.S NoInit ; => no mem? <3Dec85>
MOVE.L (A0),A0 ; get code start (already locked) <3Dec85>
JSR (A0) ; and use it <3Dec85>
DoneInit BSR ShowArrow ; restore the arrow cursor <EHB 12Aug85>
MOVEM.L (SP)+,D1-D7/A0-A4 ; restore regs <EHB 12Aug85>
MOVE.W D0,D3 ; return error in D3
RTS
NoInit MOVEQ #MFulErr,D0 ; get mem full error code <3Dec85>
BRA.S DoneInit ; => and exit <3Dec85>
;___________________________________________________________________________
;
; MFSInit writes a directory structure for a MFS volume onto the
; specified volume. See documentation for WrBlnkDir, above.
MFSInit
MOVE.L A3,A0 ; stack buffer
MOVE.W #$D2D7,(A0)+ ; signature word
MOVE.L Time,(A0)+ ; creation date
MOVE.L Time,(A0)+ ; last backup date
CLR.L (A0)+ ; volume attributes, number of files
MOVE.W #$0004,(A0)+ ; directory start block (always)
MOVE.L DriveBlks(A6),D3 ; <SHOULD MAX AT 16MB> <21Jun85>
MOVE.L D3,D2 ; disk size in 512-byte blocks
MOVE.L D3,D0
LSR.L #6,D0 ; DS/64 <MAX AT 8*ALLOC BLKS>
MOVE.L D0,D1
ADDQ #1,D1
BCLR #0,D1 ; FDB = DS/64 (make it even, though)
LSR.L #3,D0 ; DS/512
ADDQ #1,D0 ; ABBS
SUBQ.L #6,D2
SUB.L D1,D2
DIVU D0,D2 ; AB = DS-6-FDB / ABBS
MOVE.W D1,(A0)+ ; FDB = length of dir in (512-byte) blocks
MOVE.W D2,(A0)+ ; AB = number of alloc blocks this volume
LSL.L #8,D0 ; x 512 for alloc blk byte size
ADD.L D0,D0
MOVE.L D0,(A0)+ ; allocate in these byte quantities
LSL.L #3,D0
MOVE.L D0,(A0)+ ; num of bytes to try to alloc as a clump
ADDQ #4,D1 ; ASB = FBD + 4
MOVE.W D1,(A0)+ ; starting diskette (512-byte) block in map
MOVE.L #$00000001,(A0)+ ; next free file number is 1
MOVE.W D2,(A0) ; all alloc blocks are free now
LEA IOPBlk(A6),A0 ; point to general I/O param block
MOVE.L A3,IOBuffer(A0)
MOVE.L #1*BlockSize,IOByteCount(A0) ; write 1 block <GGD/25feb88>
MOVE.L #2*BlockSize,IOPosOffset(A0) ; absolute address of block 2 <GGD/25feb88>
MOVE.W #1,IOPosMode(A0) ; position mode 1 (from disk start)
_Write ; write main directory
BNE.S @3 ; exit on write errors
SUBQ.L #2,D3 ; disk size in blks - 2
LSL.L #8,D3
ADD.L D3,D3 ; x 512 for byte pos of last 2 blocks
MOVE.L D3,IOPosOffset(A0) ; put a copy at the end
_Write
BNE.S @3 ; exit on write errors
BSR ClrStkBuf ; clear the stack buffer <25 Jun 85>
MOVE.L #3*BlockSize,IOPosOffset(A0) ; absolute address of block 3 <GGD/25feb88>
_Write ; zero the other master directory block
BNE.S @3
ADDQ #4,D1 ; FBD = ASB - 4 (zero this many dir blks)
CLR.W IOPosMode(A0) ; just zero sequential blocks
@2 _Write
BNE.S @3
SUBQ #1,D1
BGT.S @2
@3 RTS ; exit with result in D0
; <PK/16Jun90>
; Subroutine to determine whether to format a volume with an MFS or HFS(TFS) file system.
; <PK/16Jun90>
; Returns with Z set iff MFS, uses D0. <PK/16Jun90>
; <PK/16Jun90>
WhichFormat
CMP.L #800,DriveBlks(A6) ; if drive is <=800 blocks, use MFS format <GGD/18feb88>
BNE.S @1 ; br if large disk <21Jun85> <2>
CMP.B #1<<(OptKeyCode**7),\ ; <GGD/25feb88>
KeyMap+(OptKeyCode/8) ; test option key down <GGD/25feb88>
BEQ.S @1 ; <**TEMP HACK**> format TFS instead <21Jun85>
MOVEQ #0,D0 ; set Z for MFS <PK/16Jun90>
RTS ; <PK/16Jun90>
@1 MOVEQ #1,D0 ; turn Z off for HFS(TFS) <PK/16Jun90>
RTS ; <PK/16Jun90>
; Subroutine to disable help balloons while formatting disk. <PK/23Aug90>
RemoveBalloons ; <PK/23Aug90>
SUB.W #2,SP ; save room for return value <PK/23Aug90>
_HMGetBalloons ; are balloons enabled? <PK/23Aug90>
MOVE.B (SP)+,HelpState(A6) ; save flag <PK/23Aug90>
BEQ.S @1 ; not enabled, so no need to disable <PK/23Aug90>
SUB.W #4,SP ; save room for return values <PK/23Aug90>
SF -(SP) ; stack a false, to turn balloons off <PK/23Aug90>
_HMSetBalloons ; turn em off <PK/23Aug90>
TST.W (SP)+ ; ignore status <PK/23Aug90>
_HMRemoveBalloon ; remove existing balloon, if any <PK/23Aug90>
TST.W (SP)+ ; ignore status <PK/23Aug90>
@1 ; <PK/23Aug90>
RTS ; <PK/23Aug90>
; Subroutine to re-enable help balloons after formatting disk. <PK/23Aug90>
RestoreBalloons ; <PK/23Aug90>
TST.B HelpState(A6) ; did we temporarily turn off balloons? <PK/23Aug90>
BEQ.S @1 ; no <PK/23Aug90>
SUB.W #2,SP ; yes, save room for return value <PK/23Aug90>
MOVE.B #1,-(SP) ; true, to turn balloons back on <PK/23Aug90>
_HMSetBalloons ; do it <PK/23Aug90>
TST.W (SP)+ ; ignore status <PK/23Aug90>
CLR.B HelpState(A6) ; avoid 2nd restoration <PK/23Aug90>
@1 ; <PK/23Aug90>
RTS ; <PK/23Aug90>
END