Hi! On Tue, May 03, 2005 at 12:31:31PM +0300, Karri Kaksonen wrote: > I have tried to understand how callirq and condes should go together > but it would be really helpful to get a small description of how I should > do this. The semantics of callirq are currently changing, and unfortunately things are not as finished as I said in my last mail regarding this topic. I will leave again for a few days tomorrow, so not much will happen before next week. > If I understand correctly I can use CONDES to put my addresses into > the _irqvecs table during the linking phase somehow. You can use either .condes or .interruptor to export symbols that the linker will arrange into a table, if told so by a CONDES directive in the linker script. As with constructors and destructors, interruptors can have a priority between 1 and 31. By default, the linker will sort these routines in order of increasing priority. The callirq routine walks over the table, starting from the last(!) entry, and calls each function in the table as a normal subroutine. This means that functions with higher numerical priority are called first. Each function must return with the carry flag set if the interrupt was handled (which means that it managed somehow to quieten the interrupt source), or carry clear if this is not the case. callirq will stop calling interruptors with the first routine that returns with carry set (assuming that the cause of the interrupt has vanished). callirq itself will the return carry set/clear depending on the last routine called. Note: this differs from the way, constructors and destructors work! The second part of interrupt handling is in calling callirq: Usually the interrupt vector is hooked in the startup code, provided that the interruptor table is not empty. The interrupt stub must save the CPU registers, call callirq and (if necessary) return the "handled" flag somehow. This latter part is platform highly dependent. Using interruptors solves a few problems: * "Installing" an interrupt handler is easy - just declare it as .interruptor, and it is called when an interrupt occurs as soon as the startup code is run. * Interrupt handlers don't need to save any registers and can return with RTS as a normal subroutine. * If interrupt handlers are installed the "usual" way, the will hook the interrupt vector, saving its old value. This means that the handlers must be deinstalled in reverse order. If this does not happen, the machine will usually crash. This is a severe problem with loadable drivers that is solved by interruptors. Drawbacks: * An interruptor is always called as long as the program runs. There is no way to install it for some time and then deinstall it. * Since interrupt latency is unknown, highly time critical interrupt handlers are a problem. Regards Uz -- Ullrich von Bassewitz uz@musoftware.de ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo@musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.Received on Wed May 4 10:36:07 2005
This archive was generated by hypermail 2.1.8 : 2005-05-04 10:36:09 CEST