home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff377.lzh
/
Formatter
/
Formatter.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-10
|
46KB
|
1,975 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by MXM
*
* Name .....: Formatter.c
* Created ..: Thursday 31-May-90 19:49
* Revision .: 4
*
* Date Author Comment
* ========= ======== ====================
* 02-Aug-90 Olsen Gadget/menu coordination fixed
* 24-Jul-90 Olsen Removed bug in formatting routine,
* added disk validation break,
* fixed the bootblock checksum
* 08-Jul-90 Olsen Sped up the formatting process
* 08-Jun-90 Olsen Added the menu
* 08-Jun-90 Olsen Fixed some bugs
* 31-May-90 Olsen Created this file!
*
****************************************************************************
*
* This file contains the main routines used by Formatter.c
*
* $Revision Header ********************************************************/
/* Prototypes for this module. */
BYTE FindDevice(char *DevName);
VOID RefreshGadget(struct Window *Window,struct Gadget *Gadget,BYTE Colour);
VOID ClearPort(VOID);
VOID AdjustClass(VOID);
VOID ConvertString(char *ToString,char *FromString);
ULONG FixBlockSum(ULONG *Array);
ULONG FixBootSum(ULONG *Array);
VOID SetBitmapBlock(ULONG *BitmapData,SHORT Block,BYTE SetFlag);
VOID ClearBlock(ULONG *Block);
VOID Inhibit(char *Drive,BYTE Bool);
BYTE CompareTracks(ULONG *Track1,ULONG *Track2);
BYTE DiskRead(BYTE Track);
BYTE DiskWrite(ULONG Offset,BYTE Track);
BYTE DiskFormat(BYTE Track);
BYTE Formatter(char *DiskName);
VOID CentreWindow(struct NewWindow *New,USHORT OffsetX,USHORT OffsetY);
VOID DecrementUsage(VOID);
VOID CloseAll(BYTE ReturnCode);
VOID OpenAll(VOID);
LONG Strlen(VOID *String);
VOID Strcpy(VOID *Dest,VOID *Source);
VOID main(int argc,char **argv);
/* Assembly language string routines. */
#pragma regcall(Strlen(a0))
#pragma regcall(Strcpy(a0,a1))
/* Window interaction. */
struct Window *Window;
struct IntuiMessage *Massage;
ULONG Class,Code;
BYTE GadgetID;
/* Global information port. */
struct FormatterPort *GlobalPort;
#define PORTNAME "Formatter"
/* Disk interaction. */
struct MsgPort *DiskPort;
struct IOExtTD *DiskRequest;
struct MsgPort *TimePort;
struct timerequest *TimeRequest;
ULONG *DiskTrack,*CheckTrack,*RootTrack;
BYTE DriveUnit = 0;
ULONG OffsetTable[NUMCYLS];
/* Debug flag. */
BYTE DebugFlag = FALSE;
/* Boolean flags. */
#define AutoStart (FormatGadget[4] . Flags & SELECTED)
#define Verify (FormatGadget[5] . Flags & SELECTED)
#define Fast (FormatGadget[6] . Flags & SELECTED)
#define Install (FormatGadget[7] . Flags & SELECTED)
#define FFS (FormatMenuItem[6].Flags & CHECKED)
/* Arp CLI info. */
char *CLI_Template = "Drive,NAME/K,F=FAST/S,I=INSTALL/S,V=VERIFY/S,A=AUTOSTART/S,FFS/S,DEBUG/S";
char *CLI_Help = "\nUsage: Formatter [DF0: | DF1: | DF2: | DF3:] [Name]\n [FAST] [INSTALL] [VERIFY] [AUTOSTART] [FFS]\n";
/* Argument vector offsets. */
#define ARG_DRIVE 1
#define ARG_NAME 2
#define ARG_FAST 3
#define ARG_INSTALL 4
#define ARG_VERIFY 5
#define ARG_AUTOSTART 6
#define ARG_FFS 7
#define ARG_DEBUG 8
/* Default font for text rendering. */
struct TextAttr DefaultFont =
{
(STRPTR)"topaz.font",
8,
FS_NORMAL,
FPF_ROMFONT
};
struct TextAttr BoldFont =
{
(STRPTR)"topaz.font",
8,
FSF_BOLD,
FPF_ROMFONT
};
/* A whole lot of intuition & graphics data. */
struct IntuiText InfoText = { 1,0,JAM1,0,25,&DefaultFont,(UBYTE *)" ",NULL };
struct IntuiText FormatIntTxt[10] =
{
{1,0,0, 21,2,&DefaultFont,(UBYTE *)"DF0:", NULL},
{1,0,0, 21,2,&DefaultFont,(UBYTE *)"DF1:", NULL},
{1,0,0, 21,2,&DefaultFont,(UBYTE *)"DF2:", NULL},
{1,0,0, 21,2,&DefaultFont,(UBYTE *)"DF3:", NULL},
{1,0,0, 20,2,&DefaultFont,(UBYTE *)"Auto start", NULL},
{1,0,0, 12,2,&DefaultFont,(UBYTE *)"Verify Write", NULL},
{1,0,0, 16,2,&DefaultFont,(UBYTE *)"Fast format", NULL},
{1,0,0, 12,2,&DefaultFont,(UBYTE *)"Install Disk", NULL},
{1,0,0, 12,9,&DefaultFont,(UBYTE *)NULL, NULL},
{1,0,0,-48,0,&DefaultFont,(UBYTE *)"Name:", NULL}
};
UBYTE FormatText[32],UndoFormatText[32];
struct StringInfo FormatStringInfo = { FormatText,UndoFormatText,0,32,32,0,0,0,0,NULL,NULL,NULL };
SHORT FormatBorderData[] =
{
-1,-1, 74,-1, 74,12,-1,12,-1,-1,
-2,-1, 75,-1, 75,12,-2,12,-2,-1,
-1,-1, 74,-1, 74,12,-1,12,-1,-1,
-2,-1, 75,-1, 75,12,-2,12,-2,-1,
-1,-1, 74,-1, 74,12,-1,12,-1,-1,
-2,-1, 75,-1, 75,12,-2,12,-2,-1,
-1,-1, 74,-1, 74,12,-1,12,-1,-1,
-2,-1, 75,-1, 75,12,-2,12,-2,-1,
-1,-1,120,-1,120,12,-1,12,-1,-1,
-2,-1,121,-1,121,12,-2,12,-2,-1,
-1,-1,120,-1,120,12,-1,12,-1,-1,
-2,-1,121,-1,121,12,-2,12,-2,-1,
-1,-1,120,-1,120,12,-1,12,-1,-1,
-2,-1,121,-1,121,12,-2,12,-2,-1,
-1,-1,120,-1,120,12,-1,12,-1,-1,
-2,-1,121,-1,121,12,-2,12,-2,-1,
-2,-1, 66,-1, 66,27,-2,27,-2,-1,
-1,-1, 65,-1, 65,27,-1,27,-1,-1,
-1,-1,256,-1,256, 8,-1, 8,-1,-1,
-2,-1,257,-1,257, 8,-2, 8,-2,-1
};
struct Border FormatBorder[] =
{
{0,0,1,0,0,5,&FormatBorderData[ 0],&FormatBorder[ 1]},
{0,0,1,0,0,5,&FormatBorderData[ 10],NULL},
{0,0,1,0,0,5,&FormatBorderData[ 20],&FormatBorder[ 3]},
{0,0,1,0,0,5,&FormatBorderData[ 30],NULL},
{0,0,1,0,0,5,&FormatBorderData[ 40],&FormatBorder[ 5]},
{0,0,1,0,0,5,&FormatBorderData[ 50],NULL},
{0,0,1,0,0,5,&FormatBorderData[ 60],&FormatBorder[ 7]},
{0,0,1,0,0,5,&FormatBorderData[ 70],NULL},
{0,0,1,0,0,5,&FormatBorderData[ 80],&FormatBorder[ 9]},
{0,0,1,0,0,5,&FormatBorderData[ 90],NULL},
{0,0,1,0,0,5,&FormatBorderData[100],&FormatBorder[11]},
{0,0,1,0,0,5,&FormatBorderData[110],NULL},
{0,0,1,0,0,5,&FormatBorderData[120],&FormatBorder[13]},
{0,0,1,0,0,5,&FormatBorderData[130],NULL},
{0,0,1,0,0,5,&FormatBorderData[140],&FormatBorder[15]},
{0,0,1,0,0,5,&FormatBorderData[150],NULL},
{0,0,1,0,0,5,&FormatBorderData[160],&FormatBorder[17]},
{0,0,1,0,0,5,&FormatBorderData[170],NULL},
{0,0,1,0,0,5,&FormatBorderData[180],&FormatBorder[19]},
{0,0,1,0,0,5,&FormatBorderData[190],NULL}
};
#define IMMEDIATE (RELVERIFY | GADGIMMEDIATE)
#define TOGGLE (RELVERIFY | GADGIMMEDIATE | TOGGLESELECT)
struct Gadget FormatGadget[10] =
{
{&FormatGadget[1], 6,67, 74,12,0,IMMEDIATE, BOOLGADGET, (APTR)&FormatBorder[ 0],NULL,&FormatIntTxt[0],NULL,NULL, 0,NULL},
{&FormatGadget[2], 87,67, 74,12,0,IMMEDIATE, BOOLGADGET, (APTR)&FormatBorder[ 2],NULL,&FormatIntTxt[1],NULL,NULL, 1,NULL},
{&FormatGadget[3],168,67, 74,12,0,IMMEDIATE, BOOLGADGET, (APTR)&FormatBorder[ 4],NULL,&FormatIntTxt[2],NULL,NULL, 2,NULL},
{&FormatGadget[4],249,67, 74,12,0,IMMEDIATE, BOOLGADGET, (APTR)&FormatBorder[ 6],NULL,&FormatIntTxt[3],NULL,NULL, 3,NULL},
{&FormatGadget[5], 6,37,120,12,0,TOGGLE, BOOLGADGET, (APTR)&FormatBorder[ 8],NULL,&FormatIntTxt[4],NULL,NULL, 4,NULL},
{&FormatGadget[6], 6,52,120,12,0,TOGGLE, BOOLGADGET, (APTR)&FormatBorder[10],NULL,&FormatIntTxt[5],NULL,NULL, 5,NULL},
{&FormatGadget[7],132,37,120,12,0,TOGGLE, BOOLGADGET, (APTR)&FormatBorder[12],NULL,&FormatIntTxt[6],NULL,NULL, 6,NULL},
{&FormatGadget[8],132,52,120,12,0,TOGGLE, BOOLGADGET, (APTR)&FormatBorder[14],NULL,&FormatIntTxt[7],NULL,NULL, 7,NULL},
{&FormatGadget[9],258,37, 65,27,0,IMMEDIATE, BOOLGADGET, (APTR)&FormatBorder[16],NULL,&FormatIntTxt[8],NULL,NULL, 8,NULL},
{NULL, 67,82,256, 8,0,IMMEDIATE, STRGADGET, (APTR)&FormatBorder[18],NULL,&FormatIntTxt[9],NULL,(APTR)&FormatStringInfo, 9,NULL}
};
UBYTE *FormatInfoText[2] =
{
(UBYTE *)" Start formatting",
(UBYTE *)" Stop formatting"
};
struct IntuiText FormatMenuIntTxt[16] =
{
{0,0,0,2,1,&DefaultFont,(UBYTE *)" About...", NULL},
{0,0,0,2,1,&BoldFont ,(UBYTE *)"_______________________", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Auto start", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Fast format", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Verify write", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Install disk", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Use FFS", NULL},
{0,0,0,2,1,&BoldFont ,(UBYTE *)"_______________________", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Drive DF0:", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Drive DF1:", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Drive DF2:", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Drive DF3:", NULL},
{0,0,0,2,1,&BoldFont ,(UBYTE *)"_______________________", NULL},
{0,0,0,2,1,&DefaultFont,NULL, NULL},
{0,0,0,2,1,&BoldFont ,(UBYTE *)"_______________________", NULL},
{0,0,0,2,1,&DefaultFont,(UBYTE *)" Quit", NULL}
};
struct MenuItem FormatMenuItem[16] =
{
{&FormatMenuItem[ 1],0, 0,188,10, 86, 0,(APTR)&FormatMenuIntTxt[ 0],NULL,63,NULL,~0L},
{&FormatMenuItem[ 2],0, 3,188,10,210, 0,(APTR)&FormatMenuIntTxt[ 1],NULL, 0,NULL,~0L},
{&FormatMenuItem[ 3],0, 13,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 2],NULL,65,NULL,~0L},
{&FormatMenuItem[ 4],0, 23,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 3],NULL,70,NULL,~0L},
{&FormatMenuItem[ 5],0, 33,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 4],NULL,86,NULL,~0L},
{&FormatMenuItem[ 6],0, 43,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 5],NULL,73,NULL,~0L},
{&FormatMenuItem[ 7],0, 53,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 6],NULL,85,NULL,~0L},
{&FormatMenuItem[ 8],0, 56,188,10,210, 0,(APTR)&FormatMenuIntTxt[ 7],NULL, 0,NULL,~0L},
{&FormatMenuItem[ 9],0, 66,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 8],NULL,49,NULL,~0L},
{&FormatMenuItem[10],0, 76,188,10, 95, 0,(APTR)&FormatMenuIntTxt[ 9],NULL,50,NULL,~0L},
{&FormatMenuItem[11],0, 86,188,10, 95, 0,(APTR)&FormatMenuIntTxt[10],NULL,51,NULL,~0L},
{&FormatMenuItem[12],0, 96,188,10, 95, 0,(APTR)&FormatMenuIntTxt[11],NULL,52,NULL,~0L},
{&FormatMenuItem[13],0, 99,188,10,210, 0,(APTR)&FormatMenuIntTxt[12],NULL, 0,NULL,~0L},
{&FormatMenuItem[14],0,109,188,10, 86, 0,(APTR)&FormatMenuIntTxt[13],NULL,83,NULL,~0L},
{&FormatMenuItem[15],0,112,188,10,210, 0,(APTR)&FormatMenuIntTxt[14],NULL, 0,NULL,~0L},
{NULL ,0,122,188,10, 86, 0,(APTR)&FormatMenuIntTxt[15],NULL,81,NULL,~0L}
};
struct Menu FormatMenu = {NULL,0,0,112,0,257,"Formatter 2.4",&FormatMenuItem[0]};
struct IntuiText ReqIntTxt[9] =
{
{2,0,0, 3, 3,&DefaultFont,(UBYTE *)"Copy me, I wish to travel!", NULL},
{2,0,0, 10, 5,&BoldFont, (UBYTE *)"Formatter 2.4a", &ReqIntTxt[2]},
{3,0,0,127, 5,&DefaultFont,(UBYTE *)"© Copyright 1990 by MXM", &ReqIntTxt[3]},
{0,0,0,127,17,&DefaultFont,(UBYTE *)"Olaf Barthel", &ReqIntTxt[4]},
{0,0,0,127,25,&DefaultFont,(UBYTE *)"Brabeckstrasse 35", &ReqIntTxt[5]},
{0,0,0,127,33,&DefaultFont,(UBYTE *)"D-3000 Hannover 71", &ReqIntTxt[6]},
{2,0,0, 67,17,&DefaultFont,(UBYTE *)"Author", &ReqIntTxt[7]},
{2,0,0, 11,45,&DefaultFont,(UBYTE *)"Shareware fee", &ReqIntTxt[8]},
{0,0,0,127,45,&DefaultFont,(UBYTE *)"7 US$ or DM 15,-", NULL}
};
SHORT ReqBorderData[] =
{
-1,-1,214,-1,214,14,-1,14,-1,-1,
-2,-1,215,-1,215,14,-2,14,-2,-1,
0, 0,311, 0,311,75, 0,75, 0, 0,
0, 0,311, 0,311,75, 0,75, 0, 0
};
struct Border ReqBorder[] =
{
{0,0,2,0,0,5,&ReqBorderData[ 0],&ReqBorder[1]},
{0,0,2,0,0,5,&ReqBorderData[10],NULL},
{4,2,0,0,0,5,&ReqBorderData[20],&ReqBorder[3]},
{5,2,0,0,0,5,&ReqBorderData[30],NULL}
};
struct Gadget ReqGadget = {NULL,53,58,214,14,0,3,4097,(APTR)&ReqBorder[0],NULL,&ReqIntTxt[0],NULL,NULL,0,NULL};
struct Requester Req;
/* A very new window (well, sort of). */
struct NewWindow NewWindow =
{
0,0,
330,93,
-1,-1,
CLOSEWINDOW | GADGETUP | MOUSEBUTTONS | MENUPICK | VANILLAKEY,
WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | ACTIVATE | RMBTRAP,
(struct Gadget *)&FormatGadget[0],
(struct Image *)NULL,
(STRPTR)"Formatter 2.4a",
(struct Screen *)NULL,
(struct BitMap *)NULL,
0,0,
0,0,
WBENCHSCREEN
};
/* The track indicator (run dump). */
USHORT PanelMap[220] =
{
0x78F0,0x0000,0x0030,0xF000,0x0000,0x78F0,0x0000,0x0078,
0xF000,0x0000,0xC0F0,0x0000,0x00FC,0xF000,0x0000,0x78F0,
0x0000,0x00FC,0xF000,0x0000,0xCD98,0x0000,0x0071,0x9800,
0x0000,0xCD98,0x0000,0x00CD,0x9800,0x0000,0xD998,0x0000,
0x00C1,0x9800,0x0000,0xC198,0x0000,0x000D,0x9800,0x0000,
0xCD98,0x0000,0x0031,0x9800,0x0000,0x1998,0x0000,0x0019,
0x9800,0x0000,0xD998,0x0000,0x00F9,0x9800,0x0000,0xF998,
0x0000,0x0019,0x9800,0x0000,0xCD98,0x0000,0x0031,0x9800,
0x0000,0x3198,0x0000,0x00CD,0x9800,0x0000,0xFD98,0x0000,
0x000D,0x9800,0x0000,0xCD98,0x0000,0x0031,0x9800,0x0000,
0x78F0,0x0000,0x0078,0xF000,0x0000,0xFCF0,0x0000,0x0078,
0xF000,0x0000,0x18F0,0x0000,0x00F8,0xF000,0x0000,0x78F0,
0x0000,0x0030,0xF000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0xC000,0x0000,0x00C0,0x0000,0x0000,0xC000,0x0000,0x00C0,
0x0000,0x0000,0xC000,0x0000,0x00C0,0x0000,0x0000,0xC000,
0x0000,0x00C0,0x0000,0x0000,0xC000,0x0000,0x00C0,0x0000,
0x0000,0xC000,0x0000,0x00C0,0x0000,0x0000,0xC000,0x0000,
0x00C0,0x0000,0x0000,0xC000,0x0000,0x00C0,0x0000,0x0000,
0xC000,0x0C00,0x00C0,0x000C,0x0000,0xC000,0x0C00,0x00C0,
0x000C,0x0000,0xC000,0x0C00,0x00C0,0x000C,0x0000,0xC000,
0x0C00,0x00C0,0x000C,0x0000,0xC000,0x0C00,0x00C0,0x000C,
0x0000,0xC000,0x0C00,0x00C0,0x000C,0x0000,0xC000,0x0C00,
0x00C0,0x000C,0x0000,0xC000,0x0C00,0x00C0,0x000C,0x0000,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF
};
/* The track indicator (the image structure). */
struct Image PanelImage =
{
0,0,
320,11,1,
(USHORT *)&PanelMap[0],
0x01,0x00,
(struct Image *)NULL
};
/* A rectangular shape. */
struct Image Box =
{
0,0,4,12,2,
(USHORT *)NULL,
0,0x03,
(struct Image *)NULL
};
/* A standard disk bootblock (as used by the install command, only the
* DOS disk ID and the checksum are missing).
*/
ULONG Standard[13] =
{
0x00000000,0x00000000,0x00000370,0x43FA0018,0x4EAEFFA0,0x4A80670A,
0x20402068,0x00167000,0x4E7570FF,0x60FA646F,0x732E6C69,0x62726172,
0x79000000
};
/* Some embedded assembly language code. */
#asm
PUBLIC _Strlen
PUBLIC _Strcpy
; Simple strlen routine.
_Strlen:
MOVEQ #0,D0 ; Reset length counter
1$ TST.B (A0)+ ; Check for end
BEQ.S 2$ ; Found it
ADDQ #1,D0 ; Increment length counter
BRA.S 1$ ; Test again
2$ RTS
; Simple strcpy routine
_Strcpy:
TST.B (A1) ; Check source byte
BEQ.S 1$ ; Found the end?
MOVE.B (A1)+,(A0)+ ; Copy the byte over
BRA.S _Strcpy ; Test again
1$ MOVE.B #0,(A0) ; Null termination
RTS
#endasm
/* FindDevice():
*
* Tries to discover a device name in the linked list
* of device nodes to be found in DosLibrary.
*/
BYTE
FindDevice(char *DevName)
{
extern struct DosLibrary *DOSBase;
char *Pointer,Name[257];
register struct DeviceNode *DevInfo;
struct RootNode *RootNode = (struct RootNode *)DOSBase -> dl_Root;
SHORT i;
/* Knock the rest of the system out. */
Forbid();
/* The starting point. */
DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(RootNode -> rn_Info)) -> di_DevInfo);
/* As long as it's valid. */
while(DevInfo)
{
/* Is it a device and does it have a file handler task attached? */
if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task)
{
/* Convert the name. */
Pointer = (char *)BADDR(DevInfo -> dn_Name);
for(i = 0 ; i < Pointer[0] ; i++)
Name[i] = Pointer[i + 1];
Name[Pointer[0] ] = ':';
Name[Pointer[0] + 1] = 0;
/* Compare the names. */
if(!Strcmp(Name,DevName))
{
Permit();
return(TRUE);
}
}
/* Check next entry. */
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
}
Permit();
return(FALSE);
}
/* RefreshGadget():
*
* Clears the background of a gadget and refreshes it.
*/
VOID
RefreshGadget(struct Window *Window,struct Gadget *Gadget,BYTE Colour)
{
struct Gadget *NextGadget = Gadget -> NextGadget;
BYTE FgPen = Window -> RPort -> FgPen;
/* Clear the background. */
SetAPen(Window -> RPort,Colour);
RectFill(Window -> RPort,Gadget -> LeftEdge,Gadget -> TopEdge,Gadget -> LeftEdge + Gadget -> Width - 1,Gadget -> TopEdge + Gadget -> Height - 1);
SetAPen(Window -> RPort,FgPen);
/* Refresh a single gadget. */
Gadget -> NextGadget = NULL;
RefreshGadgets(Gadget,Window,NULL);
Gadget -> NextGadget = NextGadget;
}
/* ClearPort():
*
* Removes all pending messages from the Window UserPort.
*/
VOID
ClearPort()
{
while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
ReplyMsg(Massage);
Class = NULL;
Code = NULL;
}
/* PerformRequest():
*
* Display the information requester in the
* formatter window.
*/
VOID
PerformRequest()
{
InitRequester(&Req);
/* I don't know how it happened, but the main
* window is an odd number of rows wide, which
* makes it somehow difficult to cover the
* window properly with the requester.
*/
Req . LeftEdge = 4;
Req . TopEdge = 11;
Req . Width = 324;
Req . Height = 80;
Req . BackFill = 1;
Req . Flags = NOISYREQ | SIMPLEREQ;
Req . ReqGadget = &ReqGadget;
Req . ReqBorder = &ReqBorder[2];
Req . ReqText = &ReqIntTxt[1];
/* Now, this gets really boring. */
if(Request(&Req,Window))
{
FOREVER
{
WaitPort(Window -> UserPort);
while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
if(Class == GADGETUP || Class == VANILLAKEY)
{
EndRequest(&Req,Window);
return;
}
}
}
}
}
/* AdjustClass():
*
* Formatter is controlled both by menu and by gadgets;
* the following routine links both interfaces.
*/
VOID
AdjustClass()
{
USHORT MenuNum = Code;
BYTE i;
/* Truly selected a menu item? */
if(MenuNum != MENUNULL)
Class = GADGETUP;
else
return;
/* Get the menu item behind the Intuition menu number. */
while(MenuNum != MENUNULL)
{
if(MENUNUM(MenuNum) == 0)
{
switch(ITEMNUM(MenuNum))
{
case 0: PerformRequest();
Class = NULL;
break;
case 2: FormatGadget[4] . Flags ^= SELECTED;
RefreshGadget(Window,&FormatGadget[4],0);
Class = NULL;
break;
case 3: FormatGadget[6] . Flags ^= SELECTED;
RefreshGadget(Window,&FormatGadget[6],0);
Class = NULL;
break;
case 4: FormatGadget[5] . Flags ^= SELECTED;
RefreshGadget(Window,&FormatGadget[5],0);
Class = NULL;
break;
case 5: FormatGadget[7] . Flags ^= SELECTED;
RefreshGadget(Window,&FormatGadget[7],0);
Class = NULL;
break;
case 8:
case 9:
case 10:
case 11:for(i = 0 ; i < 4 ; i++)
if((FormatMenuItem[8 + i] . Flags & ITEMENABLED) && 8 + i != ITEMNUM(MenuNum))
FormatMenuItem[8 + i] . Flags &= ~CHECKED;
GadgetID = ITEMNUM(MenuNum) - 8;
break;
case 13:GadgetID = 8;
break;
case 15:Class = CLOSEWINDOW;
break;
default:Class = NULL;
break;
}
}
MenuNum = ((struct MenuItem *)ItemAddress(&FormatMenu,MenuNum)) -> NextSelect;
}
}
/* ConvertString():
*
* Turn a 'C' string into a BCPL string.
*/
VOID
ConvertString(char *ToString,char *FromString)
{
*ToString++ = Strlen(FromString);
while(*FromString)
*ToString++ = *FromString++;
}
/* FixBlockSum():
*
* Calculate the checksum for a DOS disk block.
* The checksum itself is the complement of the sum
* of all the longwords contained in a track.
*/
ULONG
FixBlockSum(ULONG *Array)
{
ULONG Sum = 0;
UBYTE i = 128;
while(i--)
Sum += Array[i];
return(-Sum);
}
/* FixBootSum(ULONG *Array):
*
* Calculates the checksum for a disk bootblock, which
* unfortunately uses an algorithm different from
* FixBlockSum.
*/
ULONG
FixBootSum(ULONG *Array)
{
ULONG Sum = 0,LastSum;
UBYTE i = 128;
while(i--)
{
LastSum = Sum;
if((Sum += Array[i]) < LastSum)
Sum++;
}
return(~Sum);
}
/* SetBitmapBlock():
*
* Marks a block in the disk bitmap (bit by bit).
* A standard bitmap consists of fifty-five longwords
* in which each bit represents a disk block. If a
* bit is set, a block is unused. A cleared bit indicates
* an allocated block.
*/
VOID
SetBitmapBlock(ULONG *BitmapData,SHORT Block,BYTE SetFlag)
{
if(SetFlag)
BitmapData[Block / 32] &= ~(1 << (Block % 32));
else
BitmapData[Block / 32] |= (1 << (Block % 32));
}
/* ClearBlock():
*
* Set the contents of disk block to zero. It takes less
* time to clear the longwords contained in a disk track
* than to clear the single bytes.
*/
VOID
ClearBlock(ULONG *Block)
{
UBYTE Offset = 128;
while(Offset--)
*Block++ = 0;
}
/* Inhibit():
*
* Toggle the activity of the disk validator. We send
* a DOS packet to the file handler task telling it
* to disable or to enable the disk validator.
*/
VOID
Inhibit(char *Drive,BYTE Bool)
{
struct MsgPort *Handler;
LONG Args[7];
if(Bool)
Args[0] = DOSTRUE;
else
Args[0] = DOSFALSE;
if(Handler = DeviceProc(Drive))
SendPacket(ACTION_INHIBIT,Args,Handler);
}
/* CompareTracks():
*
* Check if two disk blocks are equal.
*/
BYTE
CompareTracks(ULONG *Track1,ULONG *Track2)
{
SHORT Size = (NUMSECS * NUMHEADS * TD_SECTOR) >> 2;
while(Size--)
if(*Track1++ != *Track2++)
return(FALSE);
return(TRUE);
}
/* DiskRead():
*
* Read a track from disk and compare it with the
* data in the buffer.
*/
BYTE
DiskRead(BYTE Track)
{
SHORT Position = 4 + Box . Width * Track;
BYTE Error;
/* Initialize the request. */
DiskRequest -> iotd_Req . io_Offset = OffsetTable[Track];
/* Start the request. */
BeginIO(DiskRequest);
/* Move up one track. */
Box . PlaneOnOff = 3;
DrawImage(Window -> RPort,&Box,Position,23);
/* News in the mail? */
if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
GadgetID = ((struct Gadget *)Massage -> IAddress) -> GadgetID;
ReplyMsg(Massage);
if(Class == MENUPICK)
AdjustClass();
if(Class == GADGETUP)
{
/* Stop formatting? */
if(GadgetID == 8)
{
/* Wait for request to be replied. */
WaitIO(DiskRequest);
/* Format aborted. */
return(-42);
}
if(GadgetID == 4)
FormatMenuItem[2] . Flags ^= CHECKED;
if(GadgetID == 6)
FormatMenuItem[3] . Flags ^= CHECKED;
if(GadgetID == 5)
FormatMenuItem[4] . Flags ^= CHECKED;
if(GadgetID == 7)
FormatMenuItem[5] . Flags ^= CHECKED;
}
}
/* Trouble? */
if(Error = WaitIO(DiskRequest))
return(Error);
/* Are both buffers equal? */
if(Track == 40)
{
if(!CompareTracks(DiskTrack,RootTrack))
{
Box . PlaneOnOff = 2;
DrawImage(Window -> RPort,&Box,Position,23);
if(DebugFlag)
{
char HelpName[20];
BPTR Help;
SPrintf(HelpName,"RAM:SRCTRACK%02ld",Track);
if(Help = Open(HelpName,MODE_NEWFILE))
{
Write(Help,RootTrack,NUMSECS * NUMHEADS * TD_SECTOR);
Close(Help);
}
SPrintf(HelpName,"RAM:DSTTRACK%02ld",Track);
if(Help = Open(HelpName,MODE_NEWFILE))
{
Write(Help,DiskTrack,NUMSECS * NUMHEADS * TD_SECTOR);
Close(Help);
}
}
/* Verification error. */
return(-43);
}
}
else
{
if(!CompareTracks(DiskTrack,CheckTrack))
{
Box . PlaneOnOff = 2;
DrawImage(Window -> RPort,&Box,Position,23);
/* Verification error. */
if(DebugFlag)
{
char HelpName[20];
BPTR Help;
SPrintf(HelpName,"RAM:SRCTRACK%02ld",Track);
if(Help = Open(HelpName,MODE_NEWFILE))
{
Write(Help,CheckTrack,NUMSECS * NUMHEADS * TD_SECTOR);
Close(Help);
}
SPrintf(HelpName,"RAM:DSTTRACK%02ld",Track);
if(Help = Open(HelpName,MODE_NEWFILE))
{
Write(Help,DiskTrack,NUMSECS * NUMHEADS * TD_SECTOR);
Close(Help);
}
}
return(-43);
}
}
return(0);
}
/* DiskWrite():
*
* Write two blocks to disk.
*/
BYTE
DiskWrite(ULONG Offset,BYTE Track)
{
SHORT Position = 4 + Box . Width * Track;
ULONG *OriginalTrack = DiskRequest -> iotd_Req . io_Data;
BYTE Error;
/* Initialize the request. */
DiskRequest -> iotd_Req . io_Command = ETD_WRITE;
DiskRequest -> iotd_Req . io_Length = TD_SECTOR * 2;
DiskRequest -> iotd_Req . io_Offset = Offset;
/* Start the request. */
BeginIO(DiskRequest);
/* Move up one track. */
Box . PlaneOnOff = 1;
DrawImage(Window -> RPort,&Box,Position,23);
/* News in the mail? */
if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
GadgetID = ((struct Gadget *)Massage -> IAddress) -> GadgetID;
ReplyMsg(Massage);
if(Class == MENUPICK)
AdjustClass();
if(Class == GADGETUP)
{
/* Stop formatting? */
if(GadgetID == 8)
{
/* Wait for request to be replied. */
WaitIO(DiskRequest);
/* Format aborted. */
return(-42);
}
if(GadgetID == 4)
FormatMenuItem[2] . Flags ^= CHECKED;
if(GadgetID == 6)
FormatMenuItem[3] . Flags ^= CHECKED;
if(GadgetID == 5)
FormatMenuItem[4] . Flags ^= CHECKED;
if(GadgetID == 7)
FormatMenuItem[5] . Flags ^= CHECKED;
}
}
/* Trouble? */
if(Error = WaitIO(DiskRequest))
return(Error);
/* Verify the data? */
if(Verify)
{
/* Make sure the buffer has been written. */
DiskRequest -> iotd_Req . io_Command = ETD_UPDATE;
DoIO(DiskRequest);
/* Reread the buffer. */
DiskRequest -> iotd_Req . io_Command = ETD_READ;
DiskRequest -> iotd_Req . io_Data = (APTR)CheckTrack;
if(Error = DoIO(DiskRequest))
return(Error);
/* Are both buffers equal? */
if(!CompareTracks(OriginalTrack,CheckTrack))
{
Box . PlaneOnOff = 2;
DrawImage(Window -> RPort,&Box,Position,23);
/* Verification error. */
return(-43);
}
Box . PlaneOnOff = 3;
DrawImage(Window -> RPort,&Box,Position,23);
}
return(0);
}
/* DiskFormat():
*
* Perform a disk write access.
*/
BYTE
DiskFormat(BYTE Track)
{
BYTE Error;
/* Initialize the request. */
DiskRequest -> iotd_Req . io_Offset = OffsetTable[Track];
if(Track == 40)
DiskRequest -> iotd_Req . io_Data = (APTR)RootTrack;
/* Start the request. */
BeginIO(DiskRequest);
/* Move up one track. */
Box . PlaneOnOff = 1;
DrawImage(Window -> RPort,&Box,4 + Box . Width * Track,23);
/* News in the mail? */
if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
GadgetID = ((struct Gadget *)Massage -> IAddress) -> GadgetID;
ReplyMsg(Massage);
if(Class == MENUPICK)
AdjustClass();
if(Class == GADGETUP)
{
/* Stop formatting? */
if(GadgetID == 8)
{
/* Wait for request to be replied. */
WaitIO(DiskRequest);
if(Track == 40)
DiskRequest -> iotd_Req . io_Data = (APTR)DiskTrack;
/* Format aborted. */
return(-42);
}
if(GadgetID == 4)
FormatMenuItem[2] . Flags ^= CHECKED;
if(GadgetID == 6)
FormatMenuItem[3] . Flags ^= CHECKED;
if(GadgetID == 5)
FormatMenuItem[4] . Flags ^= CHECKED;
if(GadgetID == 7)
FormatMenuItem[5] . Flags ^= CHECKED;
}
}
Error = WaitIO(DiskRequest);
if(Track == 40)
DiskRequest -> iotd_Req . io_Data = (APTR)DiskTrack;
return(Error);
}
/* Formatter():
*
* Format a disk drive, 3½" hardwired to the Amiga.
*/
BYTE
Formatter(char *DiskName)
{
struct DosDirectory *RootBlock;
struct DosBitmap *DosBitmap;
BYTE Error,GeneralError = FALSE;
SHORT i;
/* Allocate both auxilary buffers. */
if(CheckTrack = (ULONG *)AllocMem(NUMSECS * NUMHEADS * TD_SECTOR,MEMF_CHIP | MEMF_CLEAR))
{
if(DiskTrack = (ULONG *)AllocMem(NUMSECS * NUMHEADS * TD_SECTOR,MEMF_CHIP | MEMF_CLEAR))
{
if(RootTrack = (ULONG *)AllocMem(NUMSECS * NUMHEADS * TD_SECTOR,MEMF_CHIP | MEMF_CLEAR))
{
/* It's a DOS disk. */
if(FFS)
CheckTrack[0] = DiskTrack[0] = ID_FFS_DISK;
else
CheckTrack[0] = DiskTrack[0] = ID_DOS_DISK;
/* Tie them to the buffer. */
RootBlock = (struct DosDirectory *)RootTrack;
DosBitmap = (struct DosBitmap *)((ULONG)RootTrack + TD_SECTOR);
/* Clear the root block. */
ClearBlock((ULONG *)RootBlock);
/* Initialize the defaults. */
RootBlock -> PrimaryType = T_SHORT;
RootBlock -> SecondaryType = ST_ROOT;
RootBlock -> HashTableSize = 128 - 56;
RootBlock -> BitmapFlag = DOSFALSE;
RootBlock -> BitmapPointers[0] = (NUMTRACKS / 2) * NUMSECS + 1;
/* Set the date stamps. */
DateStamp(&RootBlock -> LastRootChange);
DateStamp(&RootBlock -> LastDiskChange);
DateStamp(&RootBlock -> CreationDate);
/* Copy the name string over. */
ConvertString(RootBlock -> DiskName,DiskName);
/* Calculate the block checksum. */
RootBlock -> CheckSum = FixBlockSum((ULONG *)RootBlock);
/* Clear the disk bitmap. */
ClearBlock((ULONG *)DosBitmap);
/* Mark all bitmap blocks as unused. */
for(i = 0 ; i < 55 ; i++)
DosBitmap -> BitmapData[i] = ~0L;
/* Mark two blocks as used (880 -> Root block, 881 -> Bitmap).
* Note that the first two blocks by default are reserved
* and, not being part of the bitmap itself, have to
* be skipped.
*/
SetBitmapBlock(DosBitmap -> BitmapData,880 - 2,TRUE);
SetBitmapBlock(DosBitmap -> BitmapData,881 - 2,TRUE);
/* Calculate the block checksum. */
DosBitmap -> CheckSum = FixBlockSum((ULONG *)DosBitmap);
/* Is there a disk in the drive? */
DiskRequest -> iotd_Req . io_Command = TD_CHANGESTATE;
DoIO(DiskRequest);
if(!DiskRequest -> iotd_Req . io_Actual)
{
/* Is the disk write enabled? */
DiskRequest -> iotd_Req . io_Command = TD_PROTSTATUS;
DoIO(DiskRequest);
if(!DiskRequest -> iotd_Req . io_Actual)
{
/* Get the disk change number. */
DiskRequest -> iotd_Req . io_Command = TD_CHANGENUM;
DoIO(DiskRequest);
/* Set the standard flags. */
DiskRequest -> iotd_Req . io_Flags = 0;
DiskRequest -> iotd_Count = DiskRequest -> iotd_Req . io_Actual;
/* Remove all messages. */
ClearPort();
/* Are we to format the whole disk? */
if(!Fast)
{
DiskRequest -> iotd_Req . io_Command = ETD_FORMAT;
DiskRequest -> iotd_Req . io_Data = (APTR)DiskTrack;
DiskRequest -> iotd_Req . io_Length = NUMSECS * NUMHEADS * TD_SECTOR;
for(i = 0 ; i < NUMCYLS ; i++)
if(Error = DiskFormat(i))
break;
if(Verify && !Error)
{
DiskRequest -> iotd_Req . io_Command = ETD_READ;
for(i = NUMCYLS - 1 ; i >= 0 && Verify ; i--)
if(Error = DiskRead(i))
break;
}
}
if(!Error)
{
if(Install || Fast)
{
ClearBlock(DiskTrack);
if(FFS)
DiskTrack[0] = ID_FFS_DISK;
else
DiskTrack[0] = ID_DOS_DISK;
/* Take the standard boot block? */
if(Install)
{
CopyMemQuick(Standard,DiskTrack,sizeof(Standard));
if(FFS)
DiskTrack[0] = ID_FFS_DISK;
else
DiskTrack[0] = ID_DOS_DISK;
DiskTrack[1] = FixBootSum(DiskTrack);
}
DiskRequest -> iotd_Req . io_Data = (APTR)DiskTrack;
if(Error = DiskWrite(0,0))
{
i = 0;
goto WriteError;
}
if(Fast)
{
DiskRequest -> iotd_Req . io_Data = (APTR)RootTrack;
if(Error = DiskWrite((NUMTRACKS / 2) * NUMSECS * TD_SECTOR,40))
{
i = 40;
goto WriteError;
}
}
}
}
else
{
WriteError: if(Error > -42)
SPrintf((char *)InfoText . IText,"Write error Nº%ld, track %ld!",Error,i);
else
{
if(Error == -42)
Strcpy((char *)InfoText . IText,"*** Format aborted ***");
else
SPrintf((char *)InfoText . IText,"Verification error on track %ld!",i);
}
GeneralError = TRUE;
}
DiskRequest -> iotd_Req . io_Command = ETD_UPDATE;
DoIO(DiskRequest);
DiskRequest -> iotd_Req . io_Command = TD_MOTOR;
DiskRequest -> iotd_Req . io_Length = 0;
DoIO(DiskRequest);
}
else
{
Strcpy(InfoText . IText,"Disk ist write protected!");
GeneralError = TRUE;
}
}
else
{
Strcpy(InfoText . IText,"No disk in drive!");
GeneralError = TRUE;
}
FreeMem(RootTrack,NUMSECS * NUMHEADS * TD_SECTOR);
}
FreeMem(DiskTrack,NUMSECS * NUMHEADS * TD_SECTOR);
}
else
{
Strcpy(InfoText . IText,"Out of memory!");
GeneralError = TRUE;
}
FreeMem(CheckTrack,NUMSECS * NUMHEADS * TD_SECTOR);
}
else
{
Strcpy(InfoText . IText,"Out of memory!");
GeneralError = TRUE;
}
ClearPort();
return(GeneralError);
}
/* CentreWindow():
*
* Centre a new window under the mouse pointer. I didn't
* want to use the req.library function for this purpose
* and wrote my own special creation.
*/
VOID
CentreWindow(struct NewWindow *New,USHORT OffsetX,USHORT OffsetY)
{
struct Screen PublicScreen;
/* Get the screen data. */
if(GetScreenData(&PublicScreen,sizeof(struct Screen),New -> Type,New -> Screen))
{
/* Put it under the mouse pointer. */
New -> LeftEdge = PublicScreen . MouseX - OffsetX;
New -> TopEdge = PublicScreen . MouseY - OffsetY;
/* Adjust the x position. */
while(New -> LeftEdge + New -> Width > PublicScreen . Width)
New -> LeftEdge--;
while(New -> LeftEdge < 0)
New -> LeftEdge++;
/* Adjust the y position. */
while(New -> TopEdge + New -> Height > PublicScreen . Height)
New -> TopEdge--;
while(New -> TopEdge < 0)
New -> TopEdge++;
}
}
/* DecrementUsage():
*
* Decrement the number of currently running Formatters
* and remove the the MsgPort if the current Formatter is
* the last one to terminate.
*/
VOID
DecrementUsage()
{
Forbid();
if(!(--GlobalPort -> NumPrgs))
{
RemPort(&GlobalPort -> Port);
FreeMem(GlobalPort,sizeof(struct FormatterPort));
}
Permit();
}
/* CloseAll():
*
* Closes devices and locks the shop.
*/
VOID
CloseAll(BYTE ReturnCode)
{
if(TimeRequest)
{
if(TimeRequest -> tr_node . io_Device)
CloseDevice(TimeRequest);
DeleteExtIO(TimeRequest);
}
if(TimePort)
DeletePort(TimePort);
if(DiskRequest)
{
if(DiskRequest -> iotd_Req . io_Device)
CloseDevice(DiskRequest);
DeleteExtIO(DiskRequest);
}
if(DiskPort)
DeletePort(DiskPort);
if(Window)
{
ClearMenuStrip(Window);
CloseWindow(Window);
}
exit(ReturnCode);
}
/* OpenAll():
*
* Opens the devices we need and also the window.
*/
VOID
OpenAll()
{
if(!(TimePort = CreatePort(NULL,0)))
CloseAll(RETURN_FAIL + 0);
if(!(TimeRequest = (struct timerequest *)CreateExtIO(TimePort,sizeof(struct timerequest))))
CloseAll(RETURN_FAIL + 1);
if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,0))
CloseAll(RETURN_FAIL + 2);
if(!(DiskPort = CreatePort(NULL,0)))
CloseAll(RETURN_FAIL + 3);
if(!(DiskRequest = (struct IOExtTD *)CreateExtIO(DiskPort,sizeof(struct IOExtTD))))
CloseAll(RETURN_FAIL + 4);
if(OpenDevice(TD_NAME,DriveUnit,DiskRequest,0))
CloseAll(RETURN_FAIL + 5);
CentreWindow(&NewWindow,FormatGadget[8] . LeftEdge + (FormatGadget[8] . Width >> 1),FormatGadget[8] . TopEdge + (FormatGadget[8] . Height >> 1));
if(!(Window = OpenWindow(&NewWindow)))
CloseAll(RETURN_FAIL + 6);
}
/* main():
*
* That's where all the trouble starts.
*/
VOID
main(int argc,char **argv)
{
static char *Drive = "DFx:";
BYTE Error,OldUnit,DiskInDrive;
ULONG Time1,Time2,Dummy;
SHORT i;
/* Try to find the global MsgPort. */
Forbid();
if(!(GlobalPort = (struct FormatterPort *)FindPort(PORTNAME)))
{
/* Didn't find it, create it now. */
if(GlobalPort = (struct FormatterPort *)AllocMem(sizeof(struct FormatterPort),MEMF_PUBLIC | MEMF_CLEAR))
{
GlobalPort -> Port . mp_Node . ln_Name = PORTNAME;
GlobalPort -> Port . mp_Node . ln_Type = NT_MSGPORT;
GlobalPort -> Port . mp_Node . ln_Pri = 1;
GlobalPort -> Port . mp_Flags = PA_IGNORE;
AddPort(&GlobalPort -> Port);
}
}
/* Increment the user count. */
if(GlobalPort)
GlobalPort -> NumPrgs++;
Permit();
/* Didn't create the port. */
if(!GlobalPort)
{
if(argc)
Printf("Formatter: Unable to create global MsgPort.\a\n");
exit(RETURN_FAIL);
}
/* Do we expect CLI arguments? */
if(argc > 1)
{
char TestString[5];
/* Enable debug? */
if(argv[ARG_DEBUG])
DebugFlag = TRUE;
/* Which disk drive? */
if(argv[ARG_DRIVE])
{
/* Does it match 'DFx:'? */
if(Strlen(argv[ARG_DRIVE]) != 4)
{
DecrementUsage();
Puts(CLI_Help);
exit(RETURN_WARN);
}
Strcpy(TestString,argv[ARG_DRIVE]);
TestString[2] = 'x';
if(Strcmp(Drive,TestString))
{
DecrementUsage();
Puts(CLI_Help);
exit(RETURN_WARN);
}
/* Can we find the device? */
if(!FindDevice(argv[ARG_DRIVE]))
{
DecrementUsage();
Printf("Formatter: Unable to find device '%s'.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
DriveUnit = argv[ARG_DRIVE][2] - '0';
}
/* Enable Auto-start? */
if(argv[ARG_AUTOSTART])
{
FormatGadget[4] . Flags |= SELECTED;
FormatMenuItem[2] . Flags |= CHECKED;
}
/* Enable verification? */
if(argv[ARG_VERIFY])
{
FormatGadget[5] . Flags |= SELECTED;
FormatMenuItem[4] . Flags |= CHECKED;
}
/* Enable fast format? */
if(argv[ARG_FAST])
{
FormatGadget[6] . Flags |= SELECTED;
FormatMenuItem[3] . Flags |= CHECKED;
}
/* Enable disk installation? */
if(argv[ARG_INSTALL])
{
FormatGadget[7] . Flags |= SELECTED;
FormatMenuItem[5] . Flags |= CHECKED;
}
if(argv[ARG_FFS])
FormatMenuItem[6] . Flags |= CHECKED;
}
Forbid();
/* Is the desired drive already occupied? */
if(argc && argv[ARG_DRIVE])
{
if(GlobalPort -> DriveInUse[DriveUnit])
{
DecrementUsage();
Permit();
Printf("Formatter: A different Formatter task is currently using device '%s'.\a\n",argv[ARG_DRIVE]);
exit(RETURN_FAIL);
}
else
GlobalPort -> DriveInUse[DriveUnit] = TRUE;
}
else
{
/* Try to find the first disk drive
* currently not in use.
*/
DriveUnit = -1;
for(i = 0 ; i < 4 ; i++)
{
if(!GlobalPort -> DriveInUse[i])
{
DriveUnit = i;
break;
}
}
/* Didn't find an unused drive. */
if(DriveUnit == -1)
{
DecrementUsage();
Permit();
DisplayBeep(NULL);
exit(RETURN_FAIL);
}
else
GlobalPort -> DriveInUse[DriveUnit] = TRUE;
}
/* Take which disk name? */
if(argc)
Strcpy(FormatText,(argv[ARG_NAME] ? argv[ARG_NAME] : "Blank"));
else
Strcpy(FormatText,"Blank");
/* Set the start gadget text. */
FormatIntTxt[8] . IText = (UBYTE *)"Start";
FormatMenuIntTxt[13] . IText = FormatInfoText[0];
/* Open the resources. */
OpenAll();
/* The timer request gets initialized. */
TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
TimeRequest -> tr_time . tv_micro = MILLION / 2;
/* Draw the track indicator. */
DrawImage(Window -> RPort,&PanelImage,4,11);
/* Mark the device gadgets. */
for(i = 0 ; i < 4 ; i++)
{
Drive[2] = '0' + i;
if(!FindDevice(Drive))
{
FormatGadget[i] . Flags |= GADGDISABLED;
FormatMenuItem[8 + i] . Flags &= ~ITEMENABLED;
}
else
FormatGadget[i] . Flags &= ~GADGDISABLED;
if(i != DriveUnit)
RefreshGadget(Window,&FormatGadget[i],0);
else
{
RefreshGadget(Window,&FormatGadget[i],3);
FormatMenuItem[8 + i] . Flags |= CHECKED;
}
}
/* Build the track offset table. */
for(i = 0 ; i < NUMCYLS ; i++)
OffsetTable[i] = i * (NUMSECS * NUMHEADS * TD_SECTOR);
/* Inhibit DFx:. */
Drive[2] = '0' + DriveUnit;
Inhibit(Drive,TRUE);
/* Is there a disk in the drive? */
DiskRequest -> iotd_Req . io_Command = TD_CHANGESTATE;
DoIO(DiskRequest);
DiskInDrive = DiskRequest -> iotd_Req . io_Actual;
/* Enable the menu. */
SetMenuStrip(Window,&FormatMenu);
Window -> Flags &= ~RMBTRAP;
/* Go into loop. */
FOREVER
{
/* Wait half a second. */
DoIO(TimeRequest);
/* Auto-start enabled? */
if(AutoStart)
{
/* Has a disk been inserted? */
DiskRequest -> iotd_Req . io_Command = TD_CHANGESTATE;
DoIO(DiskRequest);
if(!DiskRequest -> iotd_Req . io_Actual && (DiskRequest -> iotd_Req . io_Actual != DiskInDrive))
{
DiskInDrive = DiskRequest -> iotd_Req . io_Actual;
GadgetID = 8;
Class = GADGETUP;
goto CheckClass;
}
DiskInDrive = DiskRequest -> iotd_Req . io_Actual;
}
/* News in the mail? */
if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
GadgetID = ((struct Gadget *)Massage -> IAddress) -> GadgetID;
ReplyMsg(Massage);
/* Picked a menu item? */
if(Class == MENUPICK)
AdjustClass();
/* Close the window. */
if(Class == CLOSEWINDOW)
{
Drive[2] = '0' + DriveUnit;
Inhibit(Drive,FALSE);
GlobalPort -> DriveInUse[DriveUnit] = FALSE;
DecrementUsage();
CloseAll(RETURN_OK);
}
Error = 0;
/* Check the gadgets. */
CheckClass: if(Class == GADGETUP)
{
switch(GadgetID)
{
case 0:
case 1:
case 2:
case 3: OldUnit = DriveUnit;
Drive[2] = '0' + GadgetID;
if(!FindDevice(Drive))
break;
if(GadgetID != DriveUnit)
{
Forbid();
if(GlobalPort -> DriveInUse[GadgetID])
{
Permit();
DisplayBeep(Window -> WScreen);
break;
}
GlobalPort -> DriveInUse[GadgetID] = TRUE;
GlobalPort -> DriveInUse[OldUnit] = FALSE;
Permit();
Drive[2] = '0' + DriveUnit;
Inhibit(Drive,FALSE);
if(!Error)
CloseDevice(DiskRequest);
DriveUnit = GadgetID;
for(i = 0 ; i < 4 ; i++)
{
if(i != DriveUnit)
RefreshGadget(Window,&FormatGadget[i],0);
else
RefreshGadget(Window,&FormatGadget[i],3);
if((FormatMenuItem[8 + i] . Flags & ITEMENABLED) && i == DriveUnit)
FormatMenuItem[8 + i] . Flags |= CHECKED;
else
FormatMenuItem[8 + i] . Flags &= ~CHECKED;
}
Drive[2] = '0' + DriveUnit;
Inhibit(Drive,TRUE);
if(Error = OpenDevice(TD_NAME,DriveUnit,DiskRequest,0))
{
GadgetID = OldUnit;
goto CheckClass;
}
}
break;
case 4: FormatMenuItem[2] . Flags ^= CHECKED;
break;
case 5: FormatMenuItem[4] . Flags ^= CHECKED;
break;
case 6: FormatMenuItem[3] . Flags ^= CHECKED;
break;
case 7: FormatMenuItem[5] . Flags ^= CHECKED;
break;
case 8: DiskRequest -> iotd_Req . io_Command = TD_CHANGESTATE;
DoIO(DiskRequest);
DiskInDrive = DiskRequest -> iotd_Req . io_Actual;
FormatIntTxt[8] . IText = (UBYTE *)"Stop!";
RefreshGadget(Window,&FormatGadget[8],3);
for(i = 0 ; i < 4 ; i++)
FormatGadget[i] . Flags |= GADGDISABLED;
SetAPen(Window -> RPort,0);
RectFill(Window -> RPort,4,23,323,34);
SetAPen(Window -> RPort,1);
FormatGadget[4] . Flags |= GADGDISABLED;
RefreshGadget(Window,&FormatGadget[4],0);
FormatGadget[6] . Flags |= GADGDISABLED;
RefreshGadget(Window,&FormatGadget[6],0);
FormatGadget[9] . Flags |= GADGDISABLED;
RefreshGadget(Window,&FormatGadget[9],0);
FormatMenuItem[ 0] . Flags &= ~ITEMENABLED;
FormatMenuItem[ 2] . Flags &= ~ITEMENABLED;
FormatMenuItem[ 3] . Flags &= ~ITEMENABLED;
FormatMenuItem[ 6] . Flags &= ~ITEMENABLED;
FormatMenuItem[15] . Flags &= ~ITEMENABLED;
FormatMenuIntTxt[13] . IText = FormatInfoText[1];
for(i = 0 ; i < 4 ; i++)
FormatMenuItem[8 + i] . Flags &= ~ITEMENABLED;
CurrentTime(&Time1,&Dummy);
Error = Formatter((char *)FormatText);
CurrentTime(&Time2,&Dummy);
if(!Error)
{
Drive[2] = '0' + DriveUnit;
Inhibit(Drive,FALSE);
Delay(3 * TICKS_PER_SECOND);
Inhibit(Drive,TRUE);
}
FormatGadget[4] . Flags &= ~GADGDISABLED;
RefreshGadget(Window,&FormatGadget[4],0);
FormatGadget[6] . Flags &= ~GADGDISABLED;
RefreshGadget(Window,&FormatGadget[6],0);
FormatGadget[9] . Flags &= ~GADGDISABLED;
RefreshGadget(Window,&FormatGadget[9],0);
for(i = 0 ; i < 4 ; i++)
{
Drive[2] = '0' + i;
if(FindDevice(Drive))
FormatMenuItem[8 + i] . Flags |= ITEMENABLED;
}
FormatMenuItem[ 0] . Flags |= ITEMENABLED;
FormatMenuItem[ 2] . Flags |= ITEMENABLED;
FormatMenuItem[ 3] . Flags |= ITEMENABLED;
FormatMenuItem[ 6] . Flags |= ITEMENABLED;
FormatMenuItem[15] . Flags |= ITEMENABLED;
FormatMenuIntTxt[13] . IText = FormatInfoText[0];
SetAPen(Window -> RPort,0);
RectFill(Window -> RPort,4,23,323,34);
SetAPen(Window -> RPort,1);
if(Error)
{
InfoText . LeftEdge = 4 + (320 - 8 * Strlen(InfoText . IText)) / 2;
PrintIText(Window -> RPort,&InfoText,0,0);
DisplayBeep(Window -> WScreen);
}
else
{
SPrintf((char *)InfoText . IText,"Formatting time %ld:%02ld",abs(Time2 - Time1) / 60,abs(Time2 - Time1) % 60);
InfoText . LeftEdge = 4 + (320 - 8 * Strlen(InfoText . IText)) / 2;
PrintIText(Window -> RPort,&InfoText,0,0);
}
for(i = 0 ; i < 4 ; i++)
{
Drive[2] = '0' + i;
if(!FindDevice(Drive))
FormatGadget[i] . Flags |= GADGDISABLED;
else
FormatGadget[i] . Flags &= ~GADGDISABLED;
if(i != DriveUnit)
RefreshGadget(Window,&FormatGadget[i],0);
else
RefreshGadget(Window,&FormatGadget[i],3);
}
FormatIntTxt[8] . IText = (UBYTE *)"Start";
RefreshGadget(Window,&FormatGadget[8],0);
break;
default:break;
}
}
}
}
}