Important: The information in this document is obsolete and should not be used for new development.
Deferring a Slot-Based VBL Task
As indicated earlier in this chapter, you are most likely to use the Deferred Task Manager when dealing with slot interrupts. All slot interrupts, including slot-based VBL interrupts, disable all other slot interrupts. For this reason, as a slot-interrupt routine (installed usingSIntInstall
) or a slot-based VBL interrupt routine (installed usingSlotVInstall
) runs to completion, interrupts at that level and below are disabled. You can help improve interrupt handling by using the Deferred Task Manager to defer your slot-interrupt processing until interrupts have been reenabled.Listing 6-5 provides another example of how to use the Deferred Task Manager. The program defined there defers the cursor updating that would normally occur as a slot-based VBL task. The time required to update the cursor can range from about 700 to 900 microseconds for monitors having a screen depth of 1 to 8 bits. Because the cursor updating is done at slot-based VBL time, all other slot interrupts are put off
until updating is finished. This might adversely affect interrupt processing by your application. Accordingly, it is useful to defer the cursor updating to noninterrupt time by installing the updating as a deferred task.The program defined in Listing 6-5 replaces the cursor-updating routine pointed at by the system global variable
jCrsrTask
with a different routine. This new routine installs the original routine as a deferred task.Listing 6-5 Deferring cursor updating to noninterrupt time
*** MyDefTask TaskBegin MyDefTask DC.L 0 ;qLink (handled by OS) DC.W 0 ;qType (queue type: dtQType) DC.W 0 ;dtFlags (reserved) DC.L 0 ;dtAddr (pointer to routine to be executed) DC.L 0 ;dtParm (optional parameter; not used here) DC.L 0 ;dtReserved (should be zero) SysCrsrTask DC.L 0 ;pointer to system jCrsrTask DefCrsrFlag DC.W 0 ;1 if using a deferred task, 0 otherwise PendingFlag DC.W 0 ;1 if a jCrsrTask is pending, 0 otherwise *** MyjCrsrTask MyjCrsrTask MOVEM.L A0/A1/D0,-(SP) LEA PendingFlag,A0 ;see if a deferred jCrsrTask task is pending TST.W (A0) BNE.S bailOut ;if yes, exit MOVE.W #1,(A0) ;if no, set the pending flag LEA MyDefTask,A0 ;point to our deferred task element LEA DefjCrsrTask,A1 ;get address of deferred task routine MOVE.L A1,dtAddr(A0) ;set up pointer to routine MOVE.W #dtQType,dtType(A0) ;set queue type _DTInstall ;install the task MOVEM.L (SP)+,A0/A1/D0 RTS bailOut MOVEM.L (SP)+,A0/A1/D0 RTS DefjCrsrTask MOVEM.L A0,-(SP) LEA SysCrsrTask,A0 ;get system cursor task address MOVEA.L (A0),A0 JSR (A0) ;and call it LEA PendingFlag,A0 ;clear pending call flag CLR.W (A0) MOVEM.L (SP)+,A0 RTS TaskEnd *** Entry TaskSize EQU TaskEnd-TaskBegin Entry MOVE.L #TaskSize,D0 ;put TaskSize into D0 _NewPtr SYS,CLEAR ;make a block in the system heap BNE.S Quit ;no room in system heap, so quit MOVE.L 0,A2 ;got a good pointer; keep a copy MOVE.L A0,A1 ;set up registers for BlockMove LEA MyDefTask,A0 MOVE.W #TaskSize,D0 _BlockMove ;copy the task etc. into system heap LEA dtQElSize(A2),A0 ;move original task pointer into our MOVE.L jCrsrTask,(A0) ; pointer holder LEA dtQElSize+4(A2),A0;replace jCrsrTask pointer with a pointer MOVE.L A0,jCrsrTask ; to our jCrsrTask Quit RTS ;exit the program ENDThis code allocates a block of memory in the system heap. The allocated block is large enough to hold a deferred task element, a pointer to the original cursor-updating routine, and the replacement routine. The replacement routine simply retrieves the relevant information (namely, the deferred task element and the saved address of the original cursor-updating routine) stored in that block of memory and calls_DTInstall
to install a deferred task. The address of the replacement routine is placed into the low-memory global variablejCrsrTask
, whose original contents are stored in the system heap.Once the program defined in Listing 6-5 is run, the cursor-updating routine is subsequently performed with interrupts enabled, thereby allowing other interrupts. Because the cursor-updating routine is run with interrupts enabled, you may see a slight flickering of the cursor when using this technique.