105 of 172
ZBasic Language Reference 98 ZX Microcontroller Family results in undefined behavior. At a minimum, you should always include an assembly language “reti” as shown in the example below. ISR Timer1_CompB() Attribute(Naked) #asm reti #endasm End ISR On occasion, it is desirable to have the same ISR service multiple interrupts. This can be accomplished by defining an ISR that is aliased to another ISR as shown below. ISR Timer1_CompA() ' place the common ISR code here End ISR ISR Timer1_CompB() Alias Timer1_CompA End ISR You may also define a special ISR that serves all interrupts that otherwise have no ISR assigned. The default ISR is defined by using the interrupt name “default” as shown in the example below. ISR default() End ISR If you do not define a default ISR, the compiler supplies one automatically. The function of the automatically-supplied default ISR is to store in Persistent memory a fault code that indicates that an unhandled interrupt has occurred and then execute a watchdog reset. The Persistent system variable Register.FaultType will have the value 2 to indicate that an unhandled interrupt occurred. 4.4 Executing Blocks of Code Atomically Compared to writing code for the VM mode devices, when writing code for the native mode devices (e.g. ZX-24n) you must be more aware of the possibility that a sequence of statements may be interrupted either by an Interrupt Service Routine or by a task switch. Unless special techniques are used, another task or ISR may get control at any time in sequence of ZBasic statements – even in the middle of reading or writing the bytes of a multi-byte data item. If a sequence of statements must be executed without interruption (commonly referred to as a “critical section” or “atomic execution”), the only way to guarantee such atomicity is to disable interrupts before the statement(s) and re-enable interrupts after the statement(s). Clearly, one must do this carefully so that interrupts are disabled for the least time possible in order to avoid missing a frequently occurring interrupt and to ensure timely servicing of important interrupts. ZBasic supports several different techniques for disabling and re-enabling interrupts for one or more statements. Perhaps the simplest technique, and the one that is recommended for most purposes, is to use the atomic block construction. An atomic block is introduced by the keyword Atomic and is terminated by the keyword sequence End Atomic as illustrated in the example below. Dim i as Integer Sub Main() Atomic i = 200 End Atomic End Sub Of course, if this were the entire application there would be no need to be concerned about atomicity of the assignment to the variable i. However, if the variable i is also read or written by an ISR or by another task, the access to the variable should be protected as shown above.