bart@amiga.UUCP (05/08/87)
[eat this line- please] in article <1089@crash.CTS.COM>, mercurio@crash.CTS.COM (Phil Mercurio) says: > I need help with a function being called by another function attached > to the vertical blanking interval interrupt. The purpose of the > function is to scroll text onto the screen; it calls ScrollRaster() > and BltBitMap(). Some (hopefully) helpful tips on writing interrupt servers: according to the Rom Kernal Manual "certain system operations are not atomic in nature and may be interrupted after only executing part of an important instruction sequence. Take the memeory allocation and deallocation functions for example...[there is]... a finite possibility of interrupting a memory related routine. In such a case, a memory linked list may be inconsistent when examined from the interrupt code itself. To avoid serious problems, the interrupt routine must not use any of the memory allocation or deallocation functions." this means (among other things) that attempting to call ANY routine that indirectly allocated or deallocates memory is inherently dangerous from interrupt code. this includes graphics routines, which may allocate/deallocate temporary memory structures. -------------------------------------------------------------------------------- one proper means of accomplishing the desired result is this then: a) create a "slave" task which will accomplish your programming goal by calling the desired function... have this task Wait() for a specific Signal. b) install an interrupt handler on the desired interrupt chain whose sole functions are to Signal() the task which you have set up, and return(0) so that any following interrupts on the chain are serviced normally. while simple in concept, there are numerous subtle system considerations to be taken into account when implementing this approach: 1) while the interrupt handler will Signal() the "slave" task at interrupt time, the "slave" task WILL ONLY BECOME ACTIVE when it is actually resheduled by exec. if any higher priority task is ready to run, the "slave" task will NOT be the next task scheduled to run. thus, another interrupt may occur BEFORE the task does whatever useful work you have designed it for. 2) if the "slave" task IS sheduled to run BEFORE the next interrupt occurs, and if it takes too long, another interrupt may be posted before it completes. this means that as soon as the "slave" task finishes, and Wait()s again, it will immediately wake up because the Signal will already have been posted to the task. remember this, or your slave task may soak up all the system time, and not allow other tasks their fair share of the processor. 3) don't ignore the possibility that because of priority level, your "slave" task, EVEN THOUGH IT IS RECEIVING SIGNALS FROM THE INTERRUPT SERVER, conceivablymight not rescheduled until more than one interrupt has occurred. one solution for this is to have the interrupt server both post a Signal AND increment a counter variable. When the slave task is rescheduled, a quick check of the counter will tell the task how many interrupts have been posted since it last completed its function; after the quick check, the "slave" task should clear the counter to zero, so that the whole process can begin again. -------------------------------------------------------------------------------- applied to the problem initially encountered by Phil Mercurio, this approach allows the scrolling function to scroll N lines if 1 interrupt has occurred since the last scroll, or COUNT*N lines if COUNT interrupts have been posted. setting the "slave" task priority high enough to guarantee a "smooth" scroll should be balance by a Delay(timeout) before the next Wait() to allow other tasks to have their turn as well... the "count" implementation will provide a limited "catch up" capability if other tasks are not good citizens as well. amiga!bart