home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header * Header built automatically - do not edit! *************
- *
- * (C) Copyright 1990 by MXM
- *
- * Name .....: TrackDisplay.c
- * Created ..: Friday 07-Sep-90 11:03
- * Revision .: 0
- *
- * Date Author Comment
- * ========= ======== ====================
- * 07-Sep-90 Olsen Created this file!
- *
- * $Revision Header ********************************************************/
-
- /* System includes. */
-
- #include <intuition/intuitionbase.h>
- #include <libraries/dosextens.h>
- #include <workbench/startup.h>
- #include <devices/trackdisk.h>
- #include <graphics/gfxbase.h>
- #include <hardware/intbits.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <exec/alerts.h>
-
- #define __NO_PRAGMAS 1
-
- #include <functions.h>
-
- /* Global and shared data. */
-
- extern struct ExecBase *SysBase;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Window *Window;
- struct RastPort *RPort;
-
- struct Interrupt *TrackInterrupt;
-
- struct WBStartup *WBenchMsg;
-
- /* The four drive IORequests. */
-
- struct IOExtTD *TrackRequest[4];
- struct MsgPort *TrackPort[4];
-
- /* Additional track data. */
-
- SHORT TrackNumber[4];
- SHORT TrackData[4];
- BYTE TrackAvailable[4];
-
- /* Main process identifier. */
-
- struct Process *TrackProcess;
-
- /* Track offset and text spot. */
-
- BYTE Offset,Spot;
-
- /* Default title string. */
-
- char *TrackString = "DF0: -- DF1: -- DF2: -- DF3: --";
-
- /* Current directory for segment split. */
-
- BPTR RemoteCurrentDir;
-
- /* Default window, dimensions and position are filled in later. */
-
- struct NewWindow NewWindow =
- {
- 0,0,
- 0,0,
- 0,1,
- CLOSEWINDOW | ACTIVEWINDOW | INACTIVEWINDOW,
- RMBTRAP | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE,
- (struct Gadget *)NULL,
- (struct Image *)NULL,
- (UBYTE *)NULL,
- (struct Screen *)NULL,
- (struct BitMap *)NULL,
- 0,0,0,0,
- WBENCHSCREEN
- };
-
- /* TrackHandler():
- *
- * Interrupt routine to check if trackdisk.device has
- * moved the head to a different track.
- */
-
- LONG
- TrackHandler()
- {
- SHORT Number;
- SHORT i,DoSig;
-
- int_start();
-
- /* Don't send a refresh signal. */
-
- DoSig = FALSE;
-
- /* Check all drives. */
-
- for(i = 0 ; i < 4 ; i++)
- {
- /* Driver is available. */
-
- if(TrackAvailable[i])
- {
- /* This line will pick up the current
- * disk track from the approriate disk
- * unit. You may say that we are relying
- * on undefined structures. This is right
- * for Kickstart 1.3 and below, while
- * starting with Kickstart 1.4 the current
- * track indicator has moved into the public
- * portion of the trackdisk unit.
- */
-
- Number = (*(SHORT *)((ULONG)TrackRequest[i] -> iotd_Req . io_Unit + Offset) >> 1);
-
- /* Has the track number changed? */
-
- if(TrackNumber[i] == Number)
- TrackData[i] = -1;
- else
- {
- /* It has. Prepare to flag the
- * main process to update the
- * window.
- */
-
- TrackNumber[i] = TrackData[i] = Number;
- DoSig = TRUE;
- }
- }
- else
- TrackData[i] = -1;
- }
-
- /* If necessary tell the main process to update the
- * window.
- */
-
- if(DoSig)
- Signal((struct Task *)TrackProcess,SIGBREAKF_CTRL_D);
-
- int_end();
-
- return(0);
- }
-
- /* CloseAll():
- *
- * Closes everything we have allocated in order to
- * display the tracks.
- */
-
- VOID
- CloseAll()
- {
- BYTE i;
-
- /* Remove and deallocate the interrupt. */
-
- if(TrackInterrupt)
- {
- RemIntServer(INTB_VERTB,TrackInterrupt);
-
- FreeMem(TrackInterrupt,sizeof(struct Interrupt));
- }
-
- /* Free all drives. */
-
- for(i = 0 ; i < 4 ; i++)
- {
- if(TrackAvailable[i])
- CloseDevice(TrackRequest[i]);
-
- if(TrackRequest[i])
- DeleteExtIO(TrackRequest[i]);
-
- if(TrackPort[i])
- DeletePort(TrackPort[i]);
- }
-
- /* Unlock the remote directory. */
-
- if(RemoteCurrentDir)
- UnLock(RemoteCurrentDir);
-
- /* Close the window. */
-
- if(Window)
- CloseWindow(Window);
-
- /* Close the libraries. */
-
- if(GfxBase)
- CloseLibrary(GfxBase);
-
- if(IntuitionBase)
- CloseLibrary(IntuitionBase);
-
- /* Return the Workbench Message. */
-
- if(WBenchMsg)
- {
- Forbid();
- ReplyMsg(&WBenchMsg -> sm_Message);
- }
- }
-
- /* OpenAll():
- *
- * Opens everything we need to display the tracks.
- */
-
- BYTE
- OpenAll()
- {
- BYTE i;
-
- if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",LIBRARY_MINIMUM)))
- return(FALSE);
-
- if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",LIBRARY_MINIMUM)))
- return(FALSE);
-
- /* Check if we are running under control of Exec 2.x. */
-
- if(SysBase -> LibNode . lib_Version > 34)
- {
- struct Screen WBenchScreen;
-
- /* The current track is stored in the
- * 27th word behind the driver unit.
- */
-
- Offset = 54;
-
- /* Adapt the window dimensions to the current
- * system font.
- */
-
- NewWindow . Width = 20 + 24 + 31 * GfxBase -> DefaultFont -> tf_XSize;
-
- Spot = 24;
-
- if(!GetScreenData(&WBenchScreen,sizeof(struct Screen),WBENCHSCREEN,NULL))
- return(FALSE);
-
- /* Center the window. */
-
- NewWindow . LeftEdge = (WBenchScreen . Width - NewWindow . Width) >> 1;
- }
- else
- {
- struct Screen WBenchScreen;
-
- /* The current track is stored in the
- * 37th word behind the driver unit.
- */
-
- Offset = 74;
-
- /* Adapt the window dimensions to the current
- * system font.
- */
-
- NewWindow . Width = 34 + 50 + 31 * GfxBase -> DefaultFont -> tf_XSize;
-
- Spot = 30;
-
- /* Get the dimensions of the Workbench screen. */
-
- if(!GetScreenData(&WBenchScreen,sizeof(struct Screen),WBENCHSCREEN,NULL))
- return(FALSE);
-
- /* Center the window. */
-
- NewWindow . LeftEdge = (WBenchScreen . Width - NewWindow . Width) >> 1;
-
- /* Fill in the default title. */
-
- NewWindow . Title = (UBYTE *)TrackString;
- }
-
- /* Adjust the window height. */
-
- NewWindow . Height = GfxBase -> DefaultFont -> tf_YSize + 2;
-
- /* Open the window. */
-
- if(!(Window = (struct Window *)OpenWindow(&NewWindow)))
- return(FALSE);
-
- /* Open the disk drives. */
-
- for(i = 0 ; i < 4 ; i++)
- {
- if(!(TrackPort[i] = (struct MsgPort *)CreatePort(NULL,0)))
- return(FALSE);
-
- if(!(TrackRequest[i] = (struct IOExtTD *)CreateExtIO(TrackPort[i],sizeof(struct IOExtTD))))
- return(FALSE);
-
- if(!OpenDevice(TD_NAME,i,TrackRequest[i],TDF_ALLOW_NON_3_5))
- TrackAvailable[i] = TRUE;
-
- TrackNumber[i] = -1;
- }
-
- /* Allocate memory for the interrupt driver. */
-
- if(!(TrackInterrupt = (struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- RPort = Window -> RPort;
-
- /* Set the window colours according to the current
- * system colours.
- */
-
- if(SysBase -> LibNode . lib_Version > 34)
- {
- SetAPen(RPort,1);
- SetBPen(RPort,2);
- }
- else
- {
- SetAPen(RPort,0);
- SetBPen(RPort,1);
- }
-
- SetDrMd(RPort,JAM2);
-
- /* Fill in the interrupt. */
-
- TrackInterrupt -> is_Node . ln_Type = NT_INTERRUPT;
- TrackInterrupt -> is_Node . ln_Name = "Track Interrupt";
- TrackInterrupt -> is_Code = (APTR)TrackHandler;
-
- /* Add the interrupt server. */
-
- AddIntServer(INTB_VERTB,TrackInterrupt);
-
- return(TRUE);
- }
-
- /* _main():
- *
- * The main routine - performs segment split, fires off the
- * interrupt and updates the main window.
- */
-
- LONG
- _main()
- {
- STATIC char *ProcName = "Trackdisplay © Copyright 1990 by MXM, all rights reserved";
- STATIC BYTE SegmentSplit = FALSE;
-
- ULONG DeadCode = 0xDEADC0DE;
-
- ULONG SignalSet;
-
- struct IntuiMessage *Massage;
- ULONG Class;
-
- BYTE i;
-
- TrackProcess = (struct Process *)SysBase -> ThisTask;
-
- /* Are we running from a CLI? If so, perform
- * segment split.
- */
-
- if(TrackProcess -> pr_CLI)
- SegmentSplit = TRUE;
-
- /* Pick up the Workbench startup. */
-
- if(!TrackProcess -> pr_CLI && !SegmentSplit)
- {
- WaitPort(&TrackProcess -> pr_MsgPort);
-
- WBenchMsg = (struct WBStartup *)GetMsg(&TrackProcess -> pr_MsgPort);
-
- if(WBenchMsg -> sm_ArgList)
- CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
- }
-
- /* Are we to do the segment split? */
-
- if(SegmentSplit)
- {
- struct CommandLineInterface *CLI;
-
- /* Get a pointer to the current CLI structure. */
-
- if(CLI = (struct CommandLineInterface *)BADDR(TrackProcess -> pr_CLI))
- {
- /* Make a private copy of the current
- * directory Lock.
- */
-
- CurrentDir(RemoteCurrentDir = CurrentDir(NULL));
- RemoteCurrentDir = DupLock(RemoteCurrentDir);
-
- /* Create a new process from our
- * own program code.
- */
-
- if(CreateProc(ProcName,0,CLI -> cli_Module,4000))
- {
- /* Keep program segment list
- * from getting unloaded.
- */
-
- CLI -> cli_Module = NULL;
-
- return(RETURN_OK);
- }
- else
- {
- /* Oops! Process creation failed.
- * I suppose we're really broken.
- */
-
- Alert(AT_Recovery|AG_ProcCreate|AO_Unknown,&DeadCode);
-
- UnLock(RemoteCurrentDir);
-
- return(RETURN_FAIL);
- }
- }
- else
- {
- /* At this point we have a copy of the
- * lock on the current directory of
- * the creating process. We have lost
- * the link to the CLI and will need
- * to transform our segment list in order
- * to get it unloaded or at least removed
- * when we are finally falling through.
- */
-
- if(!strcmp(TrackProcess -> pr_Task . tc_Node . ln_Name,ProcName))
- {
- struct MemList *MemList;
- BPTR *SegList,*LastSeg;
- USHORT Count = 0;
-
- /* Get the pointer to our segment
- * list.
- */
-
- SegList = (BPTR *)BADDR(TrackProcess -> pr_SegList);
-
- /* The third longword points
- * to our real segment list, the
- * first two are DOS-private.
- */
-
- SegList = (BPTR *)BADDR(SegList[3]);
-
- /* Remember the segment list. */
-
- LastSeg = SegList;
-
- /* Count the number of segments. */
-
- while(SegList)
- {
- SegList = (BPTR *)BADDR(*SegList);
- Count++;
- }
-
- /* Try to allocate a MemList with
- * enough entries to hold both
- * the MemList and the segments.
- */
-
- if(MemList = (struct MemList *)AllocMem(sizeof(struct MemList) + sizeof(struct MemEntry) * (Count - 1),MEMF_PUBLIC|MEMF_CLEAR))
- {
- /* Restore the segment pointer. */
-
- SegList = LastSeg;
-
- /* Set the number of entries. */
-
- MemList -> ml_NumEntries = Count;
-
- Count = 0;
-
- /* Add all the segments to the
- * memory list.
- */
-
- while(SegList)
- {
- /* Start of segment. */
-
- MemList -> ml_me[Count] . me_Addr = (APTR)&SegList[-1];
-
- /* Length of segment. */
-
- MemList -> ml_me[Count] . me_Length = SegList[-1];
-
- /* Get pointer to next segment. */
-
- SegList = (BPTR *)BADDR(*SegList);
-
- Count++;
- }
-
- /* Add the memory list to the list
- * of memlists to be deallocated
- * on exit.
- */
-
- AddTail(&TrackProcess -> pr_Task . tc_MemEntry,&MemList -> ml_Node);
-
- /* Change to the last current
- * directory.
- */
-
- CurrentDir(RemoteCurrentDir);
- }
- else
- {
- /* AllocMem failed. We
- * will show our hand and
- * try to back out backwards.
- */
-
- Alert(AT_Recovery|AG_NoMemory|AO_Unknown,&DeadCode);
-
- UnLock(RemoteCurrentDir);
- return(RETURN_FAIL);
- }
- }
- }
- }
-
- /* We're done, now go on running the real program. */
-
- if(OpenAll())
- {
- FOREVER
- {
- /* Wait for a signal. */
-
- SignalSet = Wait((1 << Window -> UserPort -> mp_SigBit) | SIGBREAKF_CTRL_D);
-
- /* Are we to update the window? */
-
- if(SignalSet & SIGBREAKF_CTRL_D)
- {
- /* Check all drives. */
-
- for(i = 0 ; i < 4 ; i++)
- {
- /* Is the track valid? */
-
- if(TrackData[i] != -1)
- {
- /* Put the number into the
- * string.
- */
-
- TrackString[5 + 8 * i + 0] = '0' + TrackData[i] / 10;
- TrackString[5 + 8 * i + 1] = '0' + TrackData[i] % 10;
-
- /* Print the string. */
-
- Move(RPort,Spot,GfxBase -> DefaultFont -> tf_Baseline + 1);
- Text(RPort,TrackString,31);
- }
- }
- }
-
- /* Are we to close the window? */
-
- if(SignalSet & (1 << Window -> UserPort -> mp_SigBit))
- {
- while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
- {
- Class = Massage -> Class;
-
- ReplyMsg((struct Message *)Massage);
-
- /* Close the window. */
-
- if(Class == CLOSEWINDOW)
- {
- CloseAll();
-
- return(RETURN_OK);
- }
- else
- {
- /* Simply refresh
- * the contents of
- * the window.
- */
-
- Move(RPort,Spot,GfxBase -> DefaultFont -> tf_Baseline + 1);
- Text(RPort,TrackString,31);
- }
- }
- }
- }
- }
- }
-