// James Davis - jedavis@cs.stanford.edu - Copyright 1996 // Routines to make application access to deferred task manager easier #include "DeferredTask.h" typedef struct { DeferredTask theDTTask; long theA5World; DeferredTaskUPP theRealTask; } DTInfo, *DTInfoPtr; // Preallocate some space for the DeferredTask structures. Since we cant ask for // memory at interupt time we do it now in advance. Get as much as we might need. // We just get an array of the max tasks that might be active DTInfo DT_TaskInfoArray[DT_MAX_DEFERRED_TASKS]; long DT_TaskInfoCount=0; // the next taskrec to use // Get our deferred task parameter out of A1 and put it where its useful asm DTInfoPtr DT_GetTaskParm(void); asm DTInfoPtr DT_GetTaskParm(void) { move.l A1,A0 // The dtParm field is pointed to by A1 when the routine is first called // Pointers are returned in A0 so move it there... rts } // We need a stub task to reset the A5 world to our application and then call our // real task. pascal void DT_StubTask(void); pascal void DT_StubTask(void) { DTInfoPtr dtinfo; long oldA5; dtinfo = DT_GetTaskParm(); // get the param out of A1 oldA5 = SetA5(dtinfo->theA5World); // Restore the application A5 if (dtinfo->theRealTask != NULL) dtinfo->theRealTask(); // Call the task the user really wanted oldA5 = SetA5(oldA5); // reset the calling A5 } // Install a deferredtask, should only be called from interupt code. // assumes a valid aaplication a5 world on entry void DT_InstallDeferredTask(DeferredTaskUPP deferredTask) { DTInfoPtr dtinfo; // find the current taskrecord to use dtinfo= &DT_TaskInfoArray[DT_TaskInfoCount]; DT_TaskInfoCount = (DT_TaskInfoCount+1)%DT_MAX_DEFERRED_TASKS; dtinfo->theDTTask.qType=dtQType; // deferred task type dtinfo->theDTTask.dtAddr=DT_StubTask; // call our stub which sub calls the intended routine dtinfo->theDTTask.dtParam=(long)dtinfo; // our parameter to retrieve dtinfo->theDTTask.dtReserved=0; // just set it to 0, dont ask questions dtinfo->theA5World=SetCurrentA5(); // save the current a5 SetA5(dtinfo->theA5World); // restore the A5 we just blitzed dtinfo->theRealTask=deferredTask; // point to the task we want to run // install the routine in the deferred task queue DTInstall(&(dtinfo->theDTTask)); }