+\begin_layout Standard
+
+\series bold
+\InsetSpace ~
+!
+\end_layout
+
+\end_inset
+
+ without the programmer being aware of it.
+ See f.e.
+ the cast
+\family typewriter
+\series bold
+(unsigned char)(tail-1)
+\family default
+\series default
+
+\series bold
+within the if clause in section
+\begin_inset LatexCommand ref
+reference "sub:A-Step-by Assembler Introduction"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Calling other functions from an interrupt service routine is not recommended,
+ avoid it if possible.
+ Note that when some function is called from an interrupt service routine
+ it should be preceded by a #pragma\InsetSpace ~
+nooverlay
+\begin_inset LatexCommand index
+name "\\#pragma nooverlay"
+
+\end_inset
+
+ if it is not reentrant.
+ Furthermore nonreentrant functions should not be called from the main program
+ while the interrupt service routine might be active.
+ They also must not be called from low priority interrupt service routines
+ while a high priority interrupt service routine might be active.
+ You could use semaphores or make the function
+\emph on
+critical
+\emph default
+ if all parameters are passed in registers.
+\newline
+ Also see section
+\begin_inset LatexCommand ref
+reference "sub:Overlaying"
+
+\end_inset
+
+\InsetSpace ~
+about Overlaying and section
+\begin_inset LatexCommand ref
+reference "sub:Functions-using-private-banks"
+
+\end_inset
+
+\InsetSpace ~
+about Functions using private register banks.
+\begin_inset VSpace bigskip
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+MCS51/DS390 Interrupt Service Routines
+\end_layout
+
+\begin_layout Standard
+Interrupt
+\begin_inset LatexCommand index
+name "interrupt"
+
+\end_inset
+
+ numbers and the corresponding address & descriptions for the Standard 8051/8052
+ are listed below.
+ SDCC will automatically adjust the
+\begin_inset LatexCommand index
+name "interrupt vector table"
+
+\end_inset
+
+ to the maximum interrupt number specified.
+\newline
+
+\end_layout
+
+\begin_layout Standard
+\align center
+\begin_inset Tabular
+<lyxtabular version="3" rows="9" columns="3">
+<features>
+<column alignment="center" valignment="top" leftline="true" width="0in">
+<column alignment="left" valignment="top" leftline="true" width="0in">
+<column alignment="left" valignment="top" leftline="true" rightline="true" width="0in">
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Interrupt #
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Description
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Vector Address
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+External 0
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x0003
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+1
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Timer 0
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x000b
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+2
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+External 1
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x0013
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+3
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Timer 1
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x001b
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+4
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Serial
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x0023
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+5
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+Timer 2 (8052)
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x002b
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+...
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+...
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+n
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Standard
+0x0003 + 8*n
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\newline
+
+\end_layout
+
+\begin_layout Standard
+If the interrupt service routine is defined without
+\emph on
+using
+\begin_inset LatexCommand index
+name "using (mcs51, ds390 register bank)"
+
+\end_inset
+
+
+\begin_inset LatexCommand index
+name "\\_\\_using (mcs51, ds390 register bank)"
+
+\end_inset
+
+
+\emph default
+ a register bank or with register bank 0 (
+\emph on
+using
+\emph default
+ 0), the compiler will save the registers used by itself on the stack upon
+ entry and restore them at exit, however if such an interrupt service routine
+ calls another function then the entire register bank will be saved on the
+ stack.
+ This scheme may be advantageous for small interrupt service routines which
+ have low register usage.
+\end_layout
+
+\begin_layout Standard
+If the interrupt service routine is defined to be using a specific register
+ bank then only
+\emph on
+a, b, dptr
+\emph default
+ & psw are saved and restored, if such an interrupt service routine calls
+ another function (using another register bank) then the entire register
+ bank of the called function will be saved on the stack
+\begin_inset LatexCommand index
+name "stack"
+
+\end_inset
+
+.
+ This scheme is recommended for larger interrupt service routines.
+\begin_inset VSpace bigskip
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+HC08
+\begin_inset LatexCommand index
+name "HC08"
+
+\end_inset
+
+ Interrupt Service Routines
+\end_layout
+
+\begin_layout Standard
+Since the number of interrupts
+\begin_inset LatexCommand index
+name "HC08!interrupt"
+
+\end_inset
+
+ available is chip specific and the interrupt vector table always ends at
+ the last byte of memory, the interrupt numbers corresponds to the interrupt
+ vectors in reverse order of address.
+ For example, interrupt 1 will use the interrupt vector at 0xfffc, interrupt
+ 2 will use the interrupt vector at 0xfffa, and so on.
+ However, interrupt 0 (the reset vector at 0xfffe) is not redefinable in
+ this way; instead see section
+\begin_inset LatexCommand ref
+reference "sub:Startup-Code"
+
+\end_inset
+
+ for details on customizing startup.
+\begin_inset VSpace bigskip
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+Z80 Interrupt Service Routines
+\end_layout
+
+\begin_layout Standard
+The Z80
+\begin_inset LatexCommand index
+name "Z80"
+
+\end_inset
+
+ uses several different methods for determining the correct interrupt
+\begin_inset LatexCommand index
+name "Z80!interrupt"
+
+\end_inset
+
+ vector depending on the hardware implementation.
+ Therefore, SDCC ignores the optional interrupt number and does not attempt
+ to generate an interrupt vector table.
+\end_layout
+
+\begin_layout Standard
+By default, SDCC generates code for a maskable interrupt, which uses a RETI
+ instruction to return from the interrupt.
+ To write an interrupt handler for the non-maskable interrupt, which needs
+ a RETN instruction instead, add the
+\emph on
+critical
+\emph default
+ keyword:
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+void nmi_isr (void) critical interrupt
+\newline
+{
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+...
+
+\newline
+}
+\end_layout
+
+\begin_layout Standard
+However if you need to create a non-interruptable interrupt service routine
+ you would also require the
+\emph on
+critical
+\emph default
+ keyword.
+ To distinguish between this and an nmi_isr you must provide an interrupt
+ number.
+\begin_inset VSpace bigskip
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Enabling and Disabling Interrupts
+\end_layout
+
+\begin_layout Subsection
+Critical Functions and Critical Statements
+\end_layout
+
+\begin_layout Standard
+A special keyword may be associated with a block or a function declaring
+ it as
+\emph on
+critical
+\emph default
+.
+ SDCC will generate code to disable all interrupts
+\begin_inset LatexCommand index
+name "interrupt"
+
+\end_inset
+
+ upon entry to a critical function and restore the interrupt enable to the
+ previous state before returning.
+ Nesting critical functions will need one additional byte on the stack
+\begin_inset LatexCommand index
+name "stack"
+
+\end_inset
+
+ for each call.
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+int foo () __critical
+\begin_inset LatexCommand index
+name "critical"
+
+\end_inset
+
+
+\begin_inset LatexCommand index
+name "\\_\\_critical"
+
+\end_inset
+
+
+\newline
+{
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+...
+
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+...
+
+\newline
+}
+\end_layout
+
+\begin_layout Standard
+The critical attribute maybe used with other attributes like
+\emph on
+reentrant.
+\emph default
+
+\newline
+The keyword
+\emph on
+critical
+\emph default
+ may also be used to disable interrupts more locally:
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+__critical{ i++; }
+\end_layout
+
+\begin_layout Standard
+More than one statement could have been included in the block.
+\end_layout
+
+\begin_layout Subsection
+Enabling and Disabling Interrupts directly
+\end_layout
+
+\begin_layout Standard
+Interrupts
+\begin_inset LatexCommand index
+name "interrupt"
+
+\end_inset
+
+ can also be disabled and enabled directly (8051):
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+EA = 0;\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+or:\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+EA_SAVE = EA;
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+...\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+EA = 0;
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+EA = 1;\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+...
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+EA = EA_SAVE;
+\end_layout
+
+\begin_layout Standard
+On other architectures which have separate opcodes for enabling and disabling
+ interrupts you might want to make use of defines with inline assembly
+\begin_inset LatexCommand index
+name "Assembler routines"
+
+\end_inset
+
+ (HC08
+\begin_inset LatexCommand index
+name "HC08!interrupt"
+
+\end_inset
+
+):
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+#define CLI _asm
+\begin_inset LatexCommand index
+name "\\_asm"
+
+\end_inset
+
+\InsetSpace ~
+\InsetSpace ~
+cli\InsetSpace ~
+\InsetSpace ~
+_endasm
+\begin_inset LatexCommand index
+name "\\_endasm"
+
+\end_inset
+
+;
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+#define SEI _asm\InsetSpace ~
+\InsetSpace ~
+sei\InsetSpace ~
+\InsetSpace ~
+_endasm;
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+...
+\end_layout
+
+\begin_layout Standard
+Note: it is sometimes sufficient to disable only a specific interrupt source
+ like f.e.
+ a timer or serial interrupt by manipulating an
+\emph on
+interrupt mask
+\begin_inset LatexCommand index
+name "interrupt mask"
+
+\end_inset
+
+
+\emph default
+ register.
+
+\end_layout
+
+\begin_layout Standard
+Usually the time during which interrupts are disabled should be kept as
+ short as possible.
+ This minimizes both
+\emph on
+interrupt latency
+\emph default
+
+\begin_inset LatexCommand index
+name "interrupt latency"
+
+\end_inset
+
+ (the time between the occurrence of the interrupt and the execution of
+ the first code in the interrupt routine) and
+\emph on
+interrupt jitter
+\emph default
+
+\begin_inset LatexCommand index
+name "interrupt jitter"
+
+\end_inset
+
+ (the difference between the shortest and the longest interrupt latency).
+ These really are something different, f.e.
+ a serial interrupt has to be served before its buffer overruns so it cares
+ for the maximum interrupt latency, whereas it does not care about jitter.
+ On a loudspeaker driven via a digital to analog converter which is fed
+ by an interrupt a latency of a few milliseconds might be tolerable, whereas
+ a much smaller jitter will be very audible.
+\end_layout
+
+\begin_layout Standard
+You can reenable interrupts within an interrupt routine and on some architecture
+s you can make use of two (or more) levels of
+\emph on
+interrupt priorities
+\emph default
+
+\begin_inset LatexCommand index
+name "interrupt priority"
+
+\end_inset
+
+.
+ On some architectures which don't support interrupt priorities these can
+ be implemented by manipulating the interrupt mask and reenabling interrupts
+ within the interrupt routine.
+ Check there is sufficient space on the stack
+\begin_inset LatexCommand index
+name "stack"
+
+\end_inset
+
+ and don't add complexity unless you have to.
+
+\end_layout
+
+\begin_layout Subsection
+Semaphore
+\begin_inset LatexCommand index
+name "semaphore"
+
+\end_inset
+
+ locking (mcs51/ds390)
+\end_layout
+
+\begin_layout Standard
+Some architectures (mcs51/ds390) have an atomic
+\begin_inset LatexCommand index
+name "atomic"
+
+\end_inset
+
+ bit test and clear instruction.
+ These type of instructions are typically used in preemptive multitasking
+ systems, where a routine f.e.
+ claims the use of a data structure ('acquires a lock
+\begin_inset LatexCommand index
+name "lock"
+
+\end_inset
+
+ on it'), makes some modifications and then releases the lock when the data
+ structure is consistent again.
+ The instruction may also be used if interrupt and non-interrupt code have
+ to compete for a resource.
+ With the atomic bit test and clear instruction interrupts
+\begin_inset LatexCommand index
+name "interrupt"
+
+\end_inset
+
+ don't have to be disabled for the locking operation.
+
+\end_layout
+
+\begin_layout Standard
+SDCC generates this instruction if the source follows this pattern:
+\end_layout
+
+\begin_layout Verse
+
+\family typewriter
+volatile
+\begin_inset LatexCommand index
+name "volatile"
+
+\end_inset
+
+ bit resource_is_free;
+\newline
+
+\newline
+if (resource_is_free)
+\newline
+\InsetSpace ~
+\InsetSpace ~
+{
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+resource_is_free=0;
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+...
+
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+resource_is_free=1;
+\newline
+\InsetSpace ~
+\InsetSpace ~
+}
+\end_layout
+
+\begin_layout Standard
+Note, mcs51 and ds390 support only an atomic
+\begin_inset LatexCommand index
+name "atomic"
+
+\end_inset
+
+ bit test and
+\emph on
+clear
+\emph default
+ instruction (as opposed to atomic bit test and
+\emph on
+set).
+\end_layout
+
+\begin_layout Section
+Functions using private register banks
+\begin_inset LatexCommand label
+name "sub:Functions-using-private-banks"
+
+\end_inset
+
+ (mcs51/ds390)
+\end_layout
+
+\begin_layout Standard
+Some architectures have support for quickly changing register sets.
+ SDCC supports this feature with the
+\emph on
+using
+\begin_inset LatexCommand index
+name "using (mcs51, ds390 register bank)"
+
+\end_inset
+
+
+\begin_inset LatexCommand index
+name "\\_\\_using (mcs51, ds390 register bank)"
+
+\end_inset
+
+
+\emph default
+ attribute (which tells the compiler to use a register bank
+\begin_inset LatexCommand index
+name "register bank (mcs51, ds390)"
+
+\end_inset
+
+ other than the default bank zero).
+ It should only be applied to
+\emph on
+interrupt
+\begin_inset LatexCommand index
+name "interrupt"
+
+\end_inset
+
+
+\emph default
+ functions (see footnote below).
+ This will in most circumstances make the generated ISR code more efficient