mac-rom/Toolbox/DiskInit/DiskInit.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

1775 lines
84 KiB
Plaintext

;
; 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.
; <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Õ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 <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É" <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É" <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É" <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