; ; File: DiskInit.a ; ; Contains: Disk Initialization package (for Sony drives) ; ; Copyright: © 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Ő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Őt ; want to use real double quotes...use option-[ and option-shift-[ ; instead) ; <8> 5/30/90 PK Fix bug when saying ŇDisk init failed! There are open filesÉÓ, ; 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. ; 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. ; 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Őt because donŐt know what params to strip. ; - donŐ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 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 IMPORT diBadBlockPass2:CODE ; remove bad blocks from free pool OldHide EQU 1000 ; old offset used to hide dialog items NewHide EQU 16384 ; new offset, as used by ShowDItem/HideDItem cmdOptShift EQU $8005 ; command-option-shift key DlogID EQU -6079 ; TFSCode EQU -6079 ; code to write TFS directories ChEnter EQU $03 ChCR EQU $0D ChESC EQU $1B ; Escape key ChColon EQU $3A OptKeyCode EQU 58 ; Key Code for option key MaxVNameLen EQU 27 ; allow 27 chars max in a volume name VNameBufLen EQU 32 ; use a 32 byte buffer to hold the vol name BlockSize EQU 512 ; disk blocks are 512 bytes long FmtListMax EQU 16 ; max number of formats supported ; 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 itInitBut EQU 2 ; Initialize button itEjectBut EQU 3 ; Eject button itOkBut EQU 4 ; OK button for "Please name this disk" screen itInitIt EQU 5 ; "Do you want to initialize it?" itNameText EQU 6 ; "Untitled" (Edit Text) itUnReadable EQU 7 ; "This disk is unreadable:" itDamaged EQU 8 ; "This disk is damaged:" itNotMacDisk EQU 9 ; "This is not a Macintosh disk:" itNameDisk EQU 10 ; "Please name this disk:" itFormatting EQU 11 ; "Formatting disk . . ." itUndoInitIt EQU 12 ; "" (blank used to remove item 5) itInitFailed EQU 13 ; "Initialization failed!" itInitThis EQU 14 ; "Initialize this disk?" Rev1DITLlen EQU itInitThis ; original DITL just had these messages it2SidedDisk EQU 15 ; "This is a two-sided disk!" it1SidedBut EQU 16 ; One-sided button it2SidedBut EQU 17 ; Two-sided button itCancelBut EQU 18 ; Cancel button itWrProtected EQU 19 ; "This disk is write-protected." itParamText EQU 20 ; "^0" param text for reformat Rev2DITLlen EQU itParamText ; then these messages were added itVerifying EQU 21 ; "Verifying Format..." itCreatingDir EQU 22 ; "Creating Directory..." itFilesBusy EQU 23 ; "There are open files on this disk." itGCRonMFM EQU 24 ; "GCR format on High Density media" itWarnMsg EQU 25 ; "This process will erase all infoÉ" itWarnCancel EQU 26 ; cancel button for above warning itWarnErase EQU 27 ; erase button for above warning itWarnIcon EQU 28 ; warning ICON for above warning Rev3DITLlen EQU itWarnIcon ; and finally these messages were added itReVerifying EQU 29 ; "Reverifying diskÉ" itFailedOkBut EQU 30 ; OK button for "Initialization failed!" itNewFormat EQU 31 ; "This disk is in a new format..." Rev4DITLlen EQU itNewFormat ; *WARNING*: must not be > 31! ; 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 itHelpMsgs EQU 33 ; the 'hdlg' item, which points to balloon help msgs HiLiteButtons EQU (1< (1< (1< (1< (1< 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 @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? 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 MOVE.L A1,D0 ; setup address for StripAddress _StripAddress ; clean the address MOVEA.L D0,A1 ; save dispatch address LEA DiskUtilPkg,A0 ; package pointer _RecoverHandle _HGetState ; get handle state MOVE.B D0,-(SP) ; save handle state _HLock ; make sure we're locked while inside 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 _HSetState ; restore handle state RTS ; and return @5 BRA.S SubPack0 ; call package to handle mount error 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 _GetCursor MOVE.L (SP)+,A0 ; get the handle _HNoPurge ; and make it unpurgeable 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 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 _GetCursor MOVE.L (SP)+,A0 ; get the handle _HPurge ; and make it purgeable 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 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 DS.W 1 ; (word) unused for now OldPort DS.L 1 ; (long) save port DlogResult DS.W 1 ; (word) ModalDialog result theRect DS.W 4 ; (rect) item rectangle theItem DS.L 1 ; (long) item handle theType DS.W 1 ; (word) item type itemCount DS.W 1 ; (word) number of items in list, but not > 31 saveRect DS.W 4 ; (rect) place to save the old icon's rect saveIcon DS.L 1 ; (long) place to save the old icon's handle FmtParam DS.W 1 ; (word) $0001 or $0002 depending on sides to format DQElPtr DS.L 1 ; (long) drive queue element ptr DriveBlks DS.L 1 ; (long) drive size in blocks StackBuf DS.B BlockSize ; ( 512) large buffer for volname, disk blk VolNameBuf DS.B VNameBufLen ; ( 32) temp buffer for volume name IOPBlk DS.B IOVQElSize ; ( 64) parameter blk for I/O calls ; 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 FmtListLen DS.W 1 ; (word) Number of 8 byte entries in FormatList FormatList DS.B 8*FmtListMax ; list of 8 byte records of allowable fmts dftButton DS.W 1 ; (word) default button#, or 0 BadBlkHndl DS.L 1 ; (long) handle to bad block list, or NULL CheckSum DS.L 1 ; (long) partial chksum of blk 2 to identify disk HelpState DS.B 1 ; (byte) true if we have temporarily disabled help ; WARNING: DiskInitHFS.a shares this stack frame, and uses DQElPtr, DriveBlks ; StackBuf, VolNameBuf, and IOPBlk. Don't make changes that would ; cause their offsets to change. ALIGN 4 ; make the stack frame a multiple of long words FmtLinkSize DS.B 0 ; ENDR ; ; Flag bit numbers for flags stored in D5.L bReFormat equ 0 ; re-format request bEjectable equ 1 ; disk is ejectable bWrProt equ 2 ; Disk is locked (write protected) WITH FmtLocals ; use record fields SubPack0 LINK A6,#FmtLinkSize MOVEM.L D3-D5/A2,-(SP) ; preserve registers BSR ClrLocals ; clear all local variables 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 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) BSR.S GetTFSInit ; get TFS init code, if necessary _HLock ; lock it down CMP.W #diVerify,D3 ; BNE.S @6 BSR GetDriveInfo ; get the drive/disk attributes BSR FmtVerify ; code 8 means straight verify BRA GoPkg0Exit ; (it may be a mounted volume) @6 CMP.W #diFormat,D3 ; 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 BSR Format ; code 6 means straight format BRA.S GoPkg0Exit @7 CMP.W #diZero,D3 ; BNE CkErrType ; ReFormat ;; DIZero: need to do disk sparing here.; ;--------------------------------------------------------------------------------------------- BSR GetDriveInfo ; get the drive/disk attributes BSR FmtVerify ; try verifying it BEQ.S @wrtBlankDir ; skip if no bad sectors ;; If verify failed, look for bad blocks !!!! BSR WhichFormat ; MFS or HFS? BEQ Pkg0Exit ; don't bother sparing if MFS volume ; D3.W has error code from FmtVerify ;; disable sparing if 'command-option-shift' key down MOVE.W KeyMap+6,D1 ; get keys down CMP.W #cmdOptShift,D1 ; test command-option-shift key BEQ Pkg0Exit ; don't do sparing ; D3.W has error code from FmtVerify BSR ShowWatch ; no relinquish here MOVE.L D2,-(SP) ; save volname ptr PEA BadBlkHndl(A6) ; point to place to put Bad block list handle PEA StackBuf(A6) ; our buffer PEA IOPBlk(A6) ; the IO param block MOVE.L DriveBlks(A6),-(SP) ; block count BSR diBadBlockPass1 ; make a list of bad blocks LEA 4*4(SP),SP ; pop off the args MOVE.L (SP)+,D2 ; restore D2 BSR ShowArrow ; change cursor back to default TST.W D0 ; ok? Test return value. BNE.S @Fail3 ; disk is unrepairable or drive malfunction ; error code in D0 ;--------------------------------------------------------------------------------------------- @wrtBlankDir MOVE.L D2,A0 ; vol name ptr BSR WrBlnkDir ; code 10 means straight zero disk BNE.S GoPkg0Exit ; exit on error ;-------------------------------------------------------------------------------------------- MOVE.L BadBlkHndl(A6),D0 ; did we spare any bad blocks? BEQ.S @9 ; no MOVE.L D0,-(SP) ; yes, pass handle to bad block list PEA IOPBlk(A6) ; the IO param block PEA StackBuf(A6) ; the buffer BSR diBadBlockPass2 ; remove bad blocks from free list LEA 3*4(SP),SP ; pop off the args TST.W D0 ; OK? BNE.S @Fail3 ; quit if removal failed @9 ; no sparing ;-------------------------------------------------------------------------------------------- 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 MOVEQ #firstDskErr,D3 ; else, return driver error code 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 ; 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 _FlushVol ; make sure it's flushed MOVEQ #0,D0 ; restore GetVolInfo result code @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? 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> ;------------ ; Utility GetDriveInfo -- Returns Drive size, drive attributes, dialog item lists, ; formating information for the disk to be initialized. This is the only routine ; that looks at information in the drive queue element, and the only place where ; disk size is computed, since there are many special cases for the .Sony Driver. ; ; outputs are as follows: ; ; D5.L - The bWrProt and bEjectable flag bits are set ; if they apply (assumed zero on entry) ; ; FmtParam (word) - 0 if non-Sony driver which doesn't support FormatList call ; - 0..2 Number of formats if driver does support FormatList call ; clipped to 2 because user interface only allows upto 2 choices ; 400K drive would always return 1 (400K only) ; 800K drive would always return 2 (400K/800K) ; SuperDrive would return 2 (3 clipped to 2) if low density media ; SuperDrive would return 1 if HiDensity media (1440K only) ; - 1 if old Sony driver with only one choice (400K drive) ; - 2 if old Sony driver with 2 choices (800K drive) ; ; DriveBlks (long) - Size (in 512 byte blocks) of the disk currently in the drive ; ; D0.L - Bit mask of dialog items to be enabled, based on number of ; choices, and ejectability. Items are enabled as follows ; 2 - initialize button, if only one format to choose. ; 3 - eject button, if disk is ejectable ; 5 - "Do you want to initialize it?", always set ; 16 - One Sided button, if more than one format to choose ; 17 - Two Sided button, if more than one format to choose ; 18 - Cancel Button, if disk is not ejectable ; all other bits are cleared ; ; D1.L - Partial checksum of block 2 if read without error, else error code. GetDriveInfo ; MOVE.L A0,-(SP) ; Preserve A0 LEA IOPBlk(A6),A0 ; point to I/O param block ; Try to read block 2 of the disk to see what kind of error may have occured ; and to cause a disk access so that the FormatList call will return accurate info LEA StackBuf(A6),A1 ; read data into StackBuf MOVE.L A1,IOBuffer(A0) ; setup buffer address MOVE.L #1*BlockSize,IOByteCount(A0) ; read 1 block MOVE.L #2*BlockSize,IOPosOffset(A0) ; absolute address of block 2 MOVE.W #1,IOPosMode(A0) ; position mode 1 (from disk start) _Read ; try to read block #2 MOVE.W D0,DiskErrCode(A6) ; save the error code ; if the driver supports the more modern FormatList status call, use it to determine ; the actual disk size, and number of formats supported ; But first, check for the Sony driver since 3rd party drivers belly-up ; if they don't understand the Status call. Someday this will change... move.l DQElPtr(A6),a1 ; Get ptr to DQE cmp.w #DskRfn,dQRefNum(a1) ; Are we talking to the Sony driver? lea FormatList(A6),a1 ; Point to the FormatList bne.s @ComputeFmtList ; Not the Sony driver, skip the Status call... MOVE.W #FmtLstCode,CSCode(A0) ; request a list of possible formats MOVE.W #FmtListMax,CSParam(A0) ; max number of 8 byte list items we can store MOVE.L A1,CSParam+2(A0) ; list buffer pointer _Status ; make the Format List status call BEQ.S @UseFmtList ; use result if no error ; otherwise, create a format list using the information from the drive queue element @ComputeFmtList CLR.W FmtParam(A6) ; Default Format Kind to zero for now MOVEA.L DQElPtr(A6),A0 ; get pointer to drive queue element MOVE.L DQDrvSz(A0),D1 ; Vol size in 512-byte blocks (word swapped) TST.W qType(A0) ; check for new format DriveQ Element BNE.S @SwapSize ; if new format, use all 32 bits CLR.W D1 ; only first word is valid in old format @SwapSize SWAP D1 ; swap halves to form 32 bit block count MOVE.L D1,(A1) ; first long word of list is drive block count MOVE.B #$40,4(A1) ; mark current disk has this size MOVEQ.L #1,D0 ; indicate that list has just 1 entry CMPI.W #DskRfn,dQRefNum(A0) ; check for .Sony DRVR ref number? BNE.S @SearchList ; skip special cases if not .Sony Driver MOVE.W D0,IOPBlk+CSParam(A6) ; assume single sided drive, only 1 possible format MOVE.L #800,(A1) ; single sided size is 800 blocks (400K) TST.B dsSides-dsQLink(A0) ; how many sides can the drive handle? BPL.S @UseFmtList ; just one, format list is complete MOVE.L #1600,8(A1) ; double sided size is 1600 blocks (800K) CLR.B 12(A1) ; assume disk is not this format ADDQ.W #1,IOPBlk+CSParam(A6) ; list now has two entries TST.W D1 ; test twoSidedFmt (high byte of DQDrvSz) BPL.S @UseFmtList ; if single sided disk, sides/size done MOVE.B #$40,12(A1) ; indicate 800K disk in this drive CLR.B 4(A1) ; indicate 400K disk not in this drive @UseFmtList MOVE.W IOPBlk+CSParam(A6),D0 ; get the list length MOVE.W D0,FmtParam(A6) ; use last entry as default format for now BLE.S @ComputeFmtList ; ignore list if empty ; search the format list for the size of the current disk @SearchList MOVE.W D0,FmtListLen(A6) ; save number of entries on list @SearchLoop MOVE.L (A1)+,D1 ; get the disk size from the Format List BTST.B #6,(A1) ; see if current disk has this format BNE.S @FmtLstDone ; exit if it does ADDQ.L #4,A1 ; point to next list entry SUBQ.W #1,D0 ; decrement loop count BGT.S @SearchLoop ; loop through all entries @FmtLstDone ; MOVE.L D1,DriveBlks(A6) ; return block count in DriveBlks MOVEA.L DQElPtr(A6),A1 ; get pointer to drive queue element MOVE.W dsWriteProt-dsQLink(A1),D1 ; get Locked and Ejectable flag bytes BPL.S @NotLocked ; if not write protected BSET.L #bWrProt,D5 ; if locked, set flag bit @NotLocked ; MOVE.L #(1< (1< (1< (1< CMPI.B #8,D1 ; see if disk is ejectable BGE.S @NotEjectable ; if not an ejectable disk drive BSET.L #bEjectable,D5 ; if ejectable, set flag bit MOVEQ.L #(1< (1< (1< (1< @NotEjectable ; MOVEQ.L #2,D1 ; max number of formats allowed CMP.W FmtParam(A6),D1 ; compare to number we found BHI.S @DoCheckSum ; if 0 or 1 format, we are done MOVE.W D1,FmtParam(A6) ; set format kind to 2 even if more found EORI.L #(1< (1< (1< @DoCheckSum ; MOVE.W DiskErrCode(A6),D1 ; get status from read of block 2 EXT.L D1 ; BNE.S @Done ; if can't read, use error code as checksum LEA StackBuf(A6),A0 ; point to buffer block 2 was read into ADD.L drCrDate(A0),D1 ; include creation date in checksum ADD.L drLsMod(A0),D1 ; and last mod date ADD.L drVN(A0),D1 ; and first few bytes of volume name @Done MOVEA.L (SP)+,A0 ; Restore A0 RTS ; return dialog list, disk size, default fmt, flags 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 BRA.S EjectExit ; and exit, ejecting the disk @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? 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 MOVE.L D1,CheckSum(A6) ; save checksum of disk we are going to init ; now, examine the drive, disk, and error to determine the upper message GetUpperMsg MOVEQ #itUnReadable,D1 ; upper msg = "disk is unreadable" 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? BNE.S @4 ; => nope MOVEQ #it2SidedDisk,D1 ; upper msg = "Two-sided diskette Dummy" BRA.S FirstDialog ; => so do it <24 Jun 85> @4 CMPI.W #GCRonMFMErr,DiskErrCode(A6) ; if low den fmt on hi den media? BNE.S @5 ; => nope MOVEQ #itGCRonMFM,D1 ; msg = "GCR format on High Density media" BCLR.L #itInitIt,D0 ; "Initialize it?" is part of above text @5 BRA.S FirstDialog ; => so do it @1 MOVEQ #itDamaged,D1 ; upper msg = "disk is damaged" 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" CMP.W #NoMacDskErr,D3 BEQ.S @2 ; yes CMP.W #ExtFSErr,D3 ; if not recognized by any file system BNE.S @3 ; not a readable disk in unrecognized fmt @2 CMP.W #'H+',StackBuf(A6) ; future volume format? BNE.S FirstDialog ; no, say "Not a Macintosh disk" MOVEQ #itNewFormat,D1 ; yes, say "This disk is in a new formatÉ" BCLR #itInitIt,D0 ; which overwrites "Do you want to init it?" BRA.S FirstDialog ; @3 BTST.L #bReFormat,D5 ; is it an explicit reformat call? 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 MOVE.L A2,-(SP) ; dialog ptr <24 Jun 85> MOVE.W D4,-(SP) ; item number 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 MOVE.L A2,-(SP) ; dialog ptr <26 Jun 85> MOVE.W D4,-(SP) ; item number 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< (1< BSET #itCancelBut,D0 ; and turn on cancel MOVEQ #itParamText,D1 ; turn on param text message 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 ; 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 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' BSR.S GetInfo ; get the icon's info 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 @1 TST.L (A1)+ ; is the line blank DBNE d0,@1 ; loop until non-blank line found <1.4> BEQ.S @3 ; if totally blank, skip copy SUBQ.L #4,A1 ; point back to non-blank line @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 IconOk MOVE.L items(A2),A0 ; get handle to item list MOVE.L (A0),A0 ; get pointer to item list MOVE.W (A0),D4 ; get number of items-1 ADDQ.W #1,D4 ; use true count CMP.W #32,D4 ; less than 32? BLT.S @1 ; skip if <32 MOVE.L #31,D4 ; ChangeDialog can only handle 31 items @1 MOVE.W D4,ItemCount(A6) ; save number of items for ChangeDialog CMP.W #Rev4DITLlen,D4 ; old DITL? BGE.S @3 ; skip if new DITL, using NewHide ; 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# BSR GetInfo ; load theType, theItem, theRect MOVE.W theRect+2(A6),D0 ; get Left coord from rectangle CMP.W #OldHide,D0 ; hidden using old offset? BLT.S @5 ; skip if not MOVE.W #NewHide-OldHide,D0 ; its hidden, so get factor to adjust ADD.W D0,theRect+2(A6) ; change Left ADD.W D0,theRect+6(A6) ; change Right BSR SetInfo ; update the dialog item @5 SUB.W #1,D4 ; more to go? BNE.S @4 ; loop if so @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? BEQ.S Fmt2Dialog ; => yes, use current value of FmtParam CMP.W #itCancelBut-itInitBut,D0 ; cancel? (18-2) BEQ.S CancelIt ; => yes, don't eject CMP.W #itWrProtected-itInitBut,D0 ; write-protect? (19-2) BEQ.S @2 ; => keep looping CMP.W #it1SidedBut-itInitBut,D0 ; one-sided or two-sided? (16-2) BGE.S FmtDialog ; => yes, format it SUBQ.W #itEjectBut-itInitBut,D0 ; eject? (3) BNE.S @2 ; keep looping if not BTST.L #bReFormat,D5 ; was this a re-format call? BNE.S CancelIt ; default was cancel on re-format 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? BEQ.S DontEject ; => no, just exit 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 SUBQ #1,FmtParam(A6) ; unless "one sided" specifically chosen Fmt2Dialog BTST.L #bWrProt,D5 ; is disk write-protected? BNE IsLocked ; => yes BTST.L #bReFormat,D5 ; is it a re-format call? BEQ.S WarnDialog ; skip unmount if not ; Unmount the volume only if its a reformat call 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 BRA IsBusy ; exit with error WarnDialog CMPI.W #Rev3DITLlen,ItemCount(A6) ; See if we have the dialog BLT.S WarnOK ; if we don't, we can't give warning MOVE.L #(1< (1< (1< (1< BSR ChangeDialog ; put up the warning @1 LEA WarnFP,A0 ; wait for erase button BSR.S GoDlog ; call ModalDialog CMPI.W #itWarnCancel,D0 ; did the user cancel? BEQ.S EjectIt ; eject if user canceled CMPI.W #itWarnErase,D0 ; is it erase? BNE.S @1 ; keep looping if not WarnOK ; NameDialog MOVE.L #(1< (1< (1< (1< BSR ChangeDialog MOVE.L A2,-(SP) ; and select current text MOVE.W #itNameText,-(SP) ; CLR.W -(SP) ; startsel MOVE.W #100,-(SP) ; endsel _SelIText @1 LEA OKFP,A0 ; strip colons, etc. BSR GoDlog ; call ModalDialog SUBQ.W #itOkBut,D0 ; ok? BNE.S @1 ; loop until ok MOVE.L #itNameText,D4 ; get item# for 'GetInfo' BSR GetInfo ; get theType, theItem, theRect 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 _TEDeactivate ; and turn off that blinking cursor StartFormat MOVE.L #(1< (1< (1< BSR ChangeDialog ; set up appropriate fields BSR RemoveBalloons ; disable balloons while formatting ; Even though we may have preflighted resources with a _CouldDialog etc, it ; is still possible that mouse clicks outside of the dialog box or the help ; menu item have caused a disk switch if we were booted from a floppy. If ; so, we're about to init the boot disk (!), so we make *ONE LAST CHECK*. MOVE.W FmtParam(A6),-(SP) ; save 1/2-sided decision across call BSR GetDriveInfo ; recompute the checksum MOVE.W (SP)+,FmtParam(A6) ; restore decision CMP.L CheckSum(A6),D1 ; same disk? BNE FmtFail ; if last minute disk switch, abort BSR Format ; then try formatting it BNE FmtFail ; MOVE.L #(1< (1< (1< BSR ChangeDialog ; set up appropriate fields BSR FmtVerify ; try verifying it ;--------------------------------------------------------------------------------------------- ; If verify failed, look for bad blocks BEQ.S @1 ; skip if no bad sectors BSR WhichFormat ; MFS or HFS? BEQ FmtFail ; don't bother sparing if MFS volume ; D3.W has error code from FmtVerify ;; disable sparing if 'command-option-shift' key down MOVE.W KeyMap+6,D1 ; get keys down CMP.W #cmdOptShift,D1 ; test command-option-shift key BEQ FmtFail ; don't do sparing ; D3.W has error code from FmtVerify MOVE.L #(1< (1< (1< BSR ChangeDialog ; set up appropriate fields BSR ShowWatch ; no relinquish here PEA BadBlkHndl(A6) ; point to place to put Bad block list handle PEA StackBuf(A6) ; our buffer PEA IOPBlk(A6) ; the IO param block MOVE.L DriveBlks(A6),-(SP) ; block count BSR diBadBlockPass1 ; make a list of bad blocks LEA 4*4(SP),SP ; pop off the args BSR ShowArrow ; change cursor back to default MOVE.W D0,D3 ; ok? FmtFail expects error code in D3 BLE.S @negorzero ; <= 0 is OK MOVEQ #firstDskErr,D3 ; else, return driver error code @negorzero BNE FmtFail ; already negative @1 ; ;-------------------------------------------------------------------------------------------- MOVE.L #(1< (1< (1< 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 ;-------------------------------------------------------------------------------------------- MOVE.L BadBlkHndl(A6),D0 ; did we spare any bad blocks? BEQ.S @2 ; no MOVE.L D0,-(SP) ; yes, pass handle to bad block list PEA IOPBlk(A6) ; the IO param block PEA StackBuf(A6) ; the buffer BSR diBadBlockPass2 ; remove bad blocks from free list LEA 3*4(SP),SP ; pop off the args MOVE.W D0,D3 ; OK? BNE.S FmtFail ; quit if removal failed @2 ; ;-------------------------------------------------------------------------------------------- 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 BSR GetInfo ; get theType, theItem, and theRect 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 @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 _HPurge ; make it purgeable BSR RestoreBalloons ; re-enable if necessary 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< (1< (1< (1< BRA.S Fmt2Fail ; => branch around other message IsBusy MOVE.L D0,-(SP) ; preserve error code MOVE.L #(1< (1< (1< (1< BRA.S FailDialog ; display the message (but don't eject) FmtFail MOVE.L D3,-(SP) ; preserve error message MOVE.L #(1< (1< (1< (1< Fmt2Fail BSR DoEject ; eject if it's ejectable FailDialog BSR ChangeDialog ; @1 BSR RestoreBalloons ; re-enable if necessary LEA OKFP,A0 ; wait for OK button press BSR GoDlog ; call ModalDialog CMP.W #itFailedOkBut,D0 ; the special OK? BEQ.S @2 ; quit loop if so 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 BRA.S MyFilter ; EjectFP MOVEQ #itEjectBut,D0 ; return Eject item on CR, Enter BRA.S MyFilter OKFP MOVEQ #itOkBut,D0 ; filter colons, control keys out, ; 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 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? BNE.S FPExit ; exit if not escape, enter or return CMP.W #itWarnErase,D0 ; escape of "will erase all info" warning? BNE.S @2 ; no, map escape->Eject/Cancel MOVEQ #itWarnCancel,D0 ; escape of warning maps to "Cancel" @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 ; ; table to translate Rev4 dialogs to Rev3 ; dc.b itReVerifying,itVerifying ; dc.b itFailedOkBut,itOkBut ; dc.b itNewFormat,itNotMacDisk ; dc.b 0 ; ; table to translate Rev3 dialogs into Rev2 ; dc.b itVerifying,itFormatting ; dc.b itCreatingDir,itFormatting ; dc.b itFilesBusy,itUndoInitIt ; dc.b itGCRonMFM,it2SidedDisk ; dc.b 0 ; ; table to translate Rev2 dialogs into Rev1 ; dc.b it2SidedDisk,itInitIt ; dc.b it1SidedBut,itInitBut ; dc.b it2SidedBut,itInitBut ; dc.b itCancelBut,itEjectBut ; dc.b itWrProtected,itUndoInitIt ; dc.b itParamText,itInitThis ; dc.b itDamaged,itUnReadable ; dc.b itNotMacDisk,itUnReadable ; dc.b 0 ; ALIGN TranslateDITL ; MOVE.B (A0)+,D0 ; get the newer item number BEQ.S @exit ; exit when end of list MOVE.B (A0)+,D1 ; get the older item number BCLR.L D0,D3 ; test and clear the new item BEQ.S TranslateDITL ; if already clear, go to next item BSET.L D1,D3 ; otherwise, translate into older item BRA.S TranslateDITL ; go on to next item @exit RTS ; all done ChangeDialog MOVE.L D5,-(SP) ; save D5 MOVE.L #HiLiteButtons,D5 ; get bit vector of default buttons MOVE.W dftButton(A6),D4 ; is there a default button already? BEQ.S @1 ; skip if not MOVE.L #0,D0 ; yes, set flag to say "disable it" BSR.S DefaultButton ; do so @1 MOVE.W ItemCount(A6),D4 ; get item count out of stack frame LEA TranslateTable,A0 ; point to the translation table CMP.W #Rev4DITLlen,D4 ; is DITL the latest version? BGE.S ChgLoop1 ; skip if so BSR.S TranslateDITL ; if not, translate into rev3 msgs CMPI.W #Rev3DITLlen,D4 ; see if we have enough items for rev3 BGE.S ChgLoop1 ; if we do, just display it BSR.S TranslateDITL ; if not, translate it into rev2 msgs MOVEQ.L #0,D5 ; and don't frame the default buttons CMPI.W #Rev2DITLlen,D4 ; see if we have enough items for rev2 BGE.S ChgLoop1 ; if we do, just display it BSR.S TranslateDITL ; if not, translate it into rev1 msgs ChgLoop1 BTST D4,D3 ; is this item to be displayed? BNE.S @1 ; skip if so MOVE.L A2,-(SP) ; dialog ptr MOVE.W D4,-(SP) ; item number _HideDItem ; no, so hide dialog item @1 SUB.W #1,D4 ; more to go? BNE.S ChgLoop1 ; loop if so MOVE.W ItemCount(A6),D4 ; reload item count, for 2nd pass ChgLoop2 BTST D4,D3 ; is this item to be displayed? BEQ.S @1 ; no MOVE.L A2,-(SP) ; dialog ptr MOVE.W D4,-(SP) ; item number _ShowDItem ; yes, display it BTST D4,D5 ; is this a default button? BEQ.S @1 ; skip if not MOVE.L #1,D0 ; flag "enable button" function BSR.S DefaultButton ; do it @1 SUB.W #1,D4 ; more to go? BNE.S ChgLoop2 ; loop if so MOVE.L A2,-(SP) ; the window/dialog ptr _BeginUpdate ; MOVE.L A2,-(SP) ; push the dialog pointer MOVE.L visRgn(A2),-(SP) ; update against the visible region _UpdtDialog ; MOVE.L A2,-(SP) ; the window/dialog ptr _EndUpdate ; MOVE.L (SP)+,D5 ; restore D5 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 BSR GetInfo ; load theType, theItem, theRect PEA theRect(A6) ; point to rectangle MOVE.L #$FFFCFFFC,-(SP) ; (-4,-4) to make bigger _InsetRect ; adjust dimensions TST.W (SP)+ ; test and pop the on/off flag PEA theRect(A6) ; for _EraseRect or _FrameRoundRect BNE.S @1 ; skip if enabling button _EraseRect ; erase rect if disabling button CLR.W dftButton(A6) ; no dft button enabled now CLR.L theRect(A6) ; set useritem rectangle to 0... CLR.L theRect+4(A6) ; ...so we don't redraw in 'MyItem' BRA.S @2 @1 MOVE.L #$00030003,-(SP) ; (3,3) _PenSize ; set pen size for outlining buttons MOVE.L #$00100010,-(SP) ; (16,16) _FrameRoundRect ; draw the dark border MOVE.W D4,dftButton(A6) ; remember we have a dft button ; 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 MOVE.L A0,theItem(A6) ; set up MOVE.W #userItem+itemDisable,theType(A6) ; MOVE.L D4,-(SP) ; save button# MOVE.L #itUserItem,D4 ; the item# for useritem proc BSR SetInfo ; reframe the button redrawer MOVE.L (SP)+,D4 ; restore default button# RTS ; ; UserItem proc to redraw the frame around the default button ; PROCEDURE MyItem(theWindow: WindowPtr; itemNo: INTEGER); MyItem ; MOVE.L 6(SP),A1 ; get ptr to window (also dialog ptr) MOVE.W 4(SP),D1 ; get our item# SUB.W #16,SP ; save room for our var args MOVE.L SP,A0 ; copy ptr to them MOVE.L A1,-(SP) ; point to dialog MOVE.W D1,-(SP) ; item# PEA (A0) ; var: type (ignored) PEA (A0) ; var: item (ignored) PEA 4(A0) ; var: display rectangle (what we want) _GetDItem ; get our display rectangle MOVE.L #$00030003,-(SP) ; (3,3) _PenSize ; set pen size for outlining buttons LEA 4(SP),A0 ; point to rectangle PEA (A0) ; MOVE.L #$00100010,-(SP) ; (16,16) _FrameRoundRect ; draw the dark border ADD.W #16,SP ; pop off var arg storage MOVE.L (SP)+,A0 ; pop off return address ADD.W #6,SP ; pop off our parameters JMP (A0) ; back to dialog mgr ;_______________________________________________________________________ ; ; Routine: Format ; Arguments: D0.W (output) -- result code (0 if correctly formatted) ; Function: ; ;_______________________________________________________________________ Format MOVEQ #formatCC,D0 ; 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 _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 ; 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 SUBQ #4,SP ; get the watch MOVE.W #watchCursor,-(SP) ; push the id _GetCursor MOVE.L (SP)+,A0 ; get the handle MOVE.L (A0),-(SP) ; push the data ShowExit _SetCursor ; and make the watch the cursor MOVEM.L (SP)+,D0-D2/A0-A1 ; restore the little registers RTS ShowArrow MOVEM.L D0-D2/A0-A1,-(SP) ; preserve all registers MOVE.L (A5),A0 ; get pointer to QD globals PEA Arrow(A0) ; get pointer to arrow data BRA.S ShowExit ; make it the cursor, exit ;_______________________________________________________________________ ; ; ClrStkBuf (Clear Buffer) subroutine ; ClrLocals (Clear all locals) subroutine ;_______________________________________________________________________ ClrLocals MOVEM.L D0/A0,-(SP) ; LEA FmtLinkSize(A6),A0 ; get address of stack frame MOVE.W #-(FmtLinkSize/4)-1,D0 ; get number of longs (multiple of 4) 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 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 BRA.S ClrBuf ;_______________________________________________________________________ ; ; Routine: WrBlnkDir ; Arguments: (input) A0.L -- ptr to volume name for new disk ; (output) D3.W -- return error in D3. ; 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 ; format has been called. (eg. 400K before, 800K now) BSR GetDriveInfo ; get the drive/disk attributes ; 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 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 BLS.S @2 MOVE.B #MaxVNameLen,D0 ; truncate it @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 _BlockMove ; and move the name <21Jun85> BSR WhichFormat ; MFS or HFS? BNE.S DoTFS ; use HFS (aka TFS) format BSR.S MFSInit ; write an MFS directory 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 MOVEM.L (SP)+,D1-D7/A0-A4 ; restore regs 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 ; <21Jun85> MOVE.L D3,D2 ; disk size in 512-byte blocks MOVE.L D3,D0 LSR.L #6,D0 ; DS/64 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 MOVE.L #2*BlockSize,IOPosOffset(A0) ; absolute address of block 2 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 _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 ; ; Subroutine to determine whether to format a volume with an MFS or HFS(TFS) file system. ; ; Returns with Z set iff MFS, uses D0. ; WhichFormat CMP.L #800,DriveBlks(A6) ; if drive is <=800 blocks, use MFS format BNE.S @1 ; br if large disk <21Jun85> <2> CMP.B #1<<(OptKeyCode**7),\ ; KeyMap+(OptKeyCode/8) ; test option key down BEQ.S @1 ; <**TEMP HACK**> format TFS instead <21Jun85> MOVEQ #0,D0 ; set Z for MFS RTS ; @1 MOVEQ #1,D0 ; turn Z off for HFS(TFS) RTS ; ; Subroutine to disable help balloons while formatting disk. RemoveBalloons ; SUB.W #2,SP ; save room for return value _HMGetBalloons ; are balloons enabled? MOVE.B (SP)+,HelpState(A6) ; save flag BEQ.S @1 ; not enabled, so no need to disable SUB.W #4,SP ; save room for return values SF -(SP) ; stack a false, to turn balloons off _HMSetBalloons ; turn em off TST.W (SP)+ ; ignore status _HMRemoveBalloon ; remove existing balloon, if any TST.W (SP)+ ; ignore status @1 ; RTS ; ; Subroutine to re-enable help balloons after formatting disk. RestoreBalloons ; TST.B HelpState(A6) ; did we temporarily turn off balloons? BEQ.S @1 ; no SUB.W #2,SP ; yes, save room for return value MOVE.B #1,-(SP) ; true, to turn balloons back on _HMSetBalloons ; do it TST.W (SP)+ ; ignore status CLR.B HelpState(A6) ; avoid 2nd restoration @1 ; RTS ; END