+\SpecialChar ~
+dec\SpecialChar ~
+\SpecialChar ~
+a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+r3,a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+a,_head
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+cjne a,ar3,00106$
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ret
+\newline
+00106$:
+
+\newline
+;buffer.c buf[ head++ ] = c; /* access to a 256 byte aligned array */
+\begin_inset LatexCommand \index{Aligned array}
+
+\end_inset
+
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+r3,_head
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+_head
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+dpl,r3
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+dph,#(_buf >> 8)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+a,r2
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+movx @dptr,a
+
+\newline
+00103$:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ret
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+;
+\newline
+}
+
+\layout Standard
+The new file buffer.c should compile with only one warning about the unreferenced
+ function argument 'c'.
+ Now we hand-optimize the assembly code and insert an #define USE_ASSEMBLY
+ (1) and finally have:
+
+\layout Verse
+
+\family typewriter
+\size footnotesize
+unsigned char __far __at(0x7f00) buf[0x100];
+\newline
+unsigned char head, tail;
+\newline
+#define
+ USE_ASSEMBLY (1)
+\newline
+
+\newline
+#if !USE_ASSEMBLY
+\newline
+
+\newline
+void to_buffer( unsigned char c )
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+if(
+ head != (unsigned char)(tail-1) )
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+buf[ head++ ] = c;
+\newline
+}
+\newline
+
+\newline
+#else
+\newline
+
+\newline
+void to_buffer(
+ unsigned char c )
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+c; // to avoid warning: unreferenced function argument
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\begin_inset LatexCommand \index{\_asm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_asm}
+
+\end_inset
+
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; save used registers here.
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; If we were still using r2,r3 we would have to push them here.
+
+\newline
+; if( head != (unsigned char)(tail-1) )
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+ a,_tail
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dec\SpecialChar ~
+ a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+xrl\SpecialChar ~
+ a,_head
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; we
+ could do an ANL a,#0x0f here to use a smaller buffer (see below)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+jz\SpecialChar ~
+\SpecialChar ~
+ t_b_end$
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+;
+\newline
+;
+ buf[ head++ ] = c;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+ a,dpl \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; dpl holds lower byte of function argument
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+
+ dpl,_head \SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; buf is 0x100 byte aligned so head can be used directly
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+ dph,#(_bu
+f>>8)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+movx @dptr,a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc \SpecialChar ~
+_head
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; we could do an ANL _head,#0x0f here to use a
+ smaller buffer (see above)
+\newline
+t_b_end$:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; restore used registers here
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+;
+\newline
+}
+\newline
+#endif
+
+\layout Standard
+The inline assembler code can contain any valid code understood by the assembler
+, this includes any assembler directives and comment lines.
+ The assembler does not like some characters like ':' or ''' in comments.
+ You'll find an 100+ pages assembler manual in sdcc/as/doc/asxhtm.html
+\begin_inset LatexCommand \index{asXXXX (as-gbz80, as-hc08, asx8051, as-z80)}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{Assembler documentation}
+
+\end_inset
+
+ or online at
+\begin_inset LatexCommand \url{http://svn.sourceforge.net/viewvc/*checkout*/sdcc/trunk/sdcc/as/doc/asxhtm.html}
+
+\end_inset
+
+\SpecialChar ~
+.
+
+\layout Standard
+The compiler does not do any validation of the code within the
+\family typewriter
+_asm
+\begin_inset LatexCommand \index{\_asm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_asm}
+
+\end_inset
+
+ ...
+ _endasm
+\size footnotesize
+
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+
+\size default
+;
+\family default
+ keyword pair.
+ Specifically it will not know which registers are used and thus register
+ pushing/popping
+\begin_inset LatexCommand \index{push/pop}
+
+\end_inset
+
+ has to be done manually.
+
+
+\layout Standard
+It is recommended that each assembly instruction (including labels) be placed
+ in a separate line (as the example shows).
+ When the -
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+-
+\emph on
+peep-asm
+\begin_inset LatexCommand \index{-\/-peep-asm}
+
+\end_inset
+
+
+\emph default
+ command line option is used, the inline assembler code will be passed through
+ the peephole optimizer
+\begin_inset LatexCommand \index{Peephole optimizer}
+
+\end_inset
+
+.
+ There are only a few (if any) cases where this option makes sense, it might
+ cause some unexpected changes in the inline assembler code.
+ Please go through the peephole optimizer rules defined in file
+\emph on
+SDCCpeeph.def
+\emph default
+ before using this option.
+
+\layout Subsection
+Naked Functions
+\begin_inset LatexCommand \label{sub:Naked-Functions}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{Naked functions}
+
+\end_inset
+
+
+
+\layout Standard
+A special keyword may be associated with a function declaring it as
+\emph on
+_naked
+\begin_inset LatexCommand \index{\_naked}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_naked}
+
+\end_inset
+
+.
+
+\emph default
+The
+\emph on
+_naked
+\emph default
+ function modifier attribute prevents the compiler from generating prologue
+\begin_inset LatexCommand \index{function prologue}
+
+\end_inset
+
+ and epilogue
+\begin_inset LatexCommand \index{function epilogue}
+
+\end_inset
+
+ code for that function.
+ This means that the user is entirely responsible for such things as saving
+ any registers that may need to be preserved, selecting the proper register
+ bank, generating the
+\emph on
+return
+\emph default
+ instruction at the end, etc.
+ Practically, this means that the contents of the function must be written
+ in inline assembler.
+ This is particularly useful for interrupt functions, which can have a large
+ (and often unnecessary) prologue/epilogue.
+ For example, compare the code generated by these two functions:
+
+\layout Verse
+
+\family typewriter
+volatile
+\begin_inset LatexCommand \index{volatile}
+
+\end_inset
+
+ data unsigned char counter;
+\newline
+
+\newline
+void simpleInterrupt(void) __interrupt
+\begin_inset LatexCommand \index{interrupt}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_interrupt}
+
+\end_inset
+
+ (1)
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+counter++;
+\newline
+}
+\newline
+
+\newline
+void nakedInterrupt(void) __interrupt (2) __naked
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\begin_inset LatexCommand \index{\_asm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_asm}
+
+\end_inset
+
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter ; does not change flags, no need to save psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; MUST explicitly
+ include ret or reti in _naked function.
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+;
+\newline
+}
+
+\layout Standard
+For an 8051 target, the generated simpleInterrupt looks like:
+
+\layout Verse
+
+\family typewriter
+Note, this is an
+\emph on
+outdated
+\emph default
+ example, recent versions of SDCC generate
+\newline
+the
+\emph on
+same
+\emph default
+ code for simpleInterrupt() and nakedInterrupt()!
+\newline
+
+\newline
+_simpleInterrupt:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+acc
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pu
+sh\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dph
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw,#0x00
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dph
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+acc
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti
+
+\layout Standard
+whereas nakedInterrupt looks like:
+
+\layout Verse
+
+\family typewriter
+_nakedInterrupt:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter ; does not change flags, no need to save psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+;
+ MUST explicitly include ret or reti in _naked function
+
+\layout Standard
+The related directive #pragma exclude
+\begin_inset LatexCommand \index{\#pragma exclude}
+
+\end_inset
+
+ allows a more fine grained control over pushing & popping
+\begin_inset LatexCommand \index{push/pop}
+
+\end_inset
+
+ the registers.
+
+\layout Standard
+While there is nothing preventing you from writing C code inside a
+\family typewriter
+_naked
+\family default
+ function, there are many ways to shoot yourself in the foot doing this,
+ and it is recommended that you stick to inline assembler.
+
+\layout Subsection
+Use of Labels within Inline Assembler
+
+\layout Standard
+SDCC allows the use of in-line assembler with a few restrictions regarding
+ labels.
+ In older versions of the compiler all labels defined within inline assembler
+ code
+\emph on
+had to be
+\emph default
+ of the form
+\emph on
+nnnnn$
+\emph default
+ where nnnn is a number less than 100 (which implies a limit of utmost 100
+ inline assembler labels
+\emph on
+per function
+\emph default
+\noun on
+)
+\noun default
+.
+
+
+\layout Verse
+
+\family typewriter
+_asm
+\begin_inset LatexCommand \index{\_asm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_asm}
+
+\end_inset
+
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b,#10
+\newline
+00001$:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+djnz\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b,00001$
+\newline
+_endasm
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+ ;
+
+\layout Standard
+Inline assembler code cannot reference any C-Labels, however it can reference
+ labels
+\begin_inset LatexCommand \index{Labels}
+
+\end_inset
+
+ defined by the inline assembler, e.g.:
+
+\layout Verse
+
+\family typewriter
+foo() {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some c code */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; some assembler code
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ljmp $0003
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm;
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some more c code */
+\newline
+clabel:\SpecialChar ~
+\SpecialChar ~
+/* inline assembler cannot reference this
+ label */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+$0003: ;label (can be referenced by inline assembler only)
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm
+\begin_inset LatexCommand \index{\_endasm}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{\_\_endasm}
+
+\end_inset
+
+ ;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some more c code */
+\newline
+}
+
+\layout Standard
+In other words inline assembly code can access labels defined in inline
+ assembly within the scope of the function.
+ The same goes the other way, i.e.
+ labels defines in inline assembly can not be accessed by C statements.
+
+\layout Section
+Interfacing with Assembler Code
+\begin_inset LatexCommand \index{Assembler routines}
+
+\end_inset
+
+
+
+\layout Subsection
+Global Registers used for Parameter Passing
+\begin_inset LatexCommand \index{Parameter passing}
+
+\end_inset
+
+
+
+\layout Standard
+The compiler always uses the global registers
+\emph on
+DPL, DPH
+\begin_inset LatexCommand \index{DPTR, DPH, DPL}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{DPTR}
+
+\end_inset
+
+, B
+\begin_inset LatexCommand \index{B (mcs51, ds390 register)}
+
+\end_inset
+
+
+\emph default
+and
+\emph on
+ ACC
+\begin_inset LatexCommand \index{ACC (mcs51, ds390 register)}
+
+\end_inset
+
+
+\emph default
+ to pass the first parameter to a routine.
+ The second parameter onwards is either allocated on the stack (for reentrant
+ routines or if -
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+-stack-auto is used) or in data / xdata memory (depending on the memory
+ model).
+
+
+\layout Subsection
+Assembler Routine (non-reentrant)
+
+\layout Standard
+In the following example
+\begin_inset LatexCommand \index{reentrant}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{Assembler routines (non-reentrant)}
+
+\end_inset
+
+ the function c_func calls an assembler routine asm_func, which takes two
+ parameters
+\begin_inset LatexCommand \index{function parameter}
+
+\end_inset
+
+.
+
+\layout Verse
+
+\family typewriter
+extern int asm_func(unsigned char, unsigned char);
+\newline
+
+\newline
+int c_func (unsigned char
+ i, unsigned char j)
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+return asm_func(i,j);
+\newline
+}
+\newline
+
+\newline
+int main()
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+return c_func(10,9);
+\newline
+}
+
+\layout Standard
+The corresponding assembler function is:
+
+\layout Verse
+
+\family typewriter
+.globl _asm_func_PARM_2
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.globl _asm_func
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.area OSEG
+\newline
+_asm_func_PARM_2:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.ds
+ 1
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+.area CSEG
+\newline
+_asm_func:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+a,dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+add\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+a,_asm_func_PARM_2
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dpl,a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dph
+\begin_inset LatexCommand \index{DPTR, DPH, DPL}
+
+\end_inset
+
+,#0x00
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ret
+
+\layout Standard
+Note here that the return values
+\begin_inset LatexCommand \index{return value}
+
+\end_inset
+
+ are placed in 'dpl' - One byte return value, 'dpl' LSB & 'dph' MSB for
+ two byte values.
+ 'dpl', 'dph' and 'b' for three byte values (generic pointers) and 'dpl','dph','
+b' & 'acc' for four byte values.
+
+\layout Standard
+The parameter naming convention is _<function_name>_PARM_<n>, where n is
+ the parameter number starting from 1, and counting from the left.
+ The first parameter is passed in
+\begin_inset Quotes eld
+\end_inset
+
+dpl
+\begin_inset Quotes erd
+\end_inset
+
+ for a one byte parameter,
+\begin_inset Quotes eld
+\end_inset
+
+dptr
+\begin_inset Quotes erd
+\end_inset
+
+ for two bytes,
+\begin_inset Quotes eld
+\end_inset
+
+b,dptr
+\begin_inset Quotes erd
+\end_inset
+
+ for three bytes and
+\begin_inset Quotes eld
+\end_inset
+
+acc,b,dptr
+\begin_inset Quotes erd
+\end_inset
+
+ for a four bytes parameter.
+ The variable name for the second parameter will be _<function_name>_PARM_2.
+\newline
+
+\newline
+Assem
+ble the assembler routine with the following command:
+\newline
+
+\newline
+
+\family sans
+\series bold
+asx8051 -losg asmfunc.asm
+\newline
+
+\newline
+
+\family default
+\series default
+Then compile and link the assembler routine to the C source file with the
+ following command:
+\newline
+
+\newline
+
+\family sans
+\series bold
+sdcc cfunc.c asmfunc.rel
+
+\layout Subsection
+Assembler Routine (reentrant)
+
+\layout Standard
+In this case
+\begin_inset LatexCommand \index{reentrant}
+
+\end_inset
+
+
+\begin_inset LatexCommand \index{Assembler routines (reentrant)}
+
+\end_inset
+
+ the second parameter
+\begin_inset LatexCommand \index{function parameter}
+
+\end_inset
+
+ onwards will be passed on the stack, the parameters are pushed from right
+ to left i.e.
+ after the call the leftmost parameter will be on the top of the stack.
+ Here is an example:
+
+\layout Verse
+
+\family typewriter
+extern int asm_func(unsigned char, unsigned char);
+\newline
+
+\newline
+int c_func (unsigned char
+ i, unsigned char j) reentrant
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+return asm_func(i,j);
+\newline
+}
+\newline
+
+\newline
+int main()
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+return
+ c_func(10,9);
+\newline
+}
+
+\layout Standard
+The corresponding assembler routine is:
+
+\layout Verse
+
+\family typewriter
+.globl _asm_func
+\newline
+_asm_func:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push _bp
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov _bp,sp
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov r2,dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov a,_bp
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+add
+ a,#0xfd
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov r0,a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+add a,#0xfc ;?
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov r1,a
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov a,@r0
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+add a,r2 ;?
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov dpl,a
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov dph,#0x00
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov sp,_bp
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop _bp
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ret
+
+\layout Standard
+\added_space_bottom bigskip
+The compiling and linking procedure remains the same, however note the extra
+ entry & exit linkage required for the assembler code, _bp is the stack
+ frame pointer and is used to compute the offset into the stack for parameters
+ and local variables.
+
+
+
+\layout Section
+int (16 bit)
+\begin_inset LatexCommand \index{int (16 bit)}
+
+\end_inset
+
+ and long (32 bit)
+\begin_inset LatexCommand \index{long (32 bit)}
+
+\end_inset
+
+ Support
+
+\layout Standard
+For signed & unsigned int (16 bit) and long (32 bit) variables, division,
+ multiplication and modulus operations are implemented by support routines.
+ These support routines are all developed in ANSI-C to facilitate porting
+ to other MCUs, although some model specific assembler optimizations are
+ used.
+ The following files contain the described routines, all of them can be
+ found in <installdir>/share/sdcc/lib.
+\newline
+
+
+\layout Standard
+\align center
+\begin_inset Tabular
+<lyxtabular version="3" rows="11" columns="2">
+<features>
+<column alignment="left" valignment="top" leftline="true" width="0">
+<column alignment="left" valignment="top" leftline="true" rightline="true" width="0">
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\series bold
+Function
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\series bold
+Description
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_mulint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+16 bit multiplication
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_divsint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+ signed 16 bit division (calls _divuint)
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_divuint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+ unsigned 16 bit division
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_modsint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+signed 16 bit modulus (calls _moduint)
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_moduint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+unsigned 16 bit modulus
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_mullong.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+32 bit multiplication
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_divslong.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+ signed 32 division (calls _divulong)
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_divulong.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+unsigned 32 division
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_modslong.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+ signed 32 bit modulus (calls _modulong)
+
+\end_inset
+</cell>
+</row>
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+_modulong.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+unsigned 32 bit modulus
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\newline
+
+
+\layout Standard
+Since they are compiled as
+\emph on
+non-reentrant
+\emph default
+
+\begin_inset LatexCommand \index{reentrant}
+
+\end_inset
+
+, interrupt
+\begin_inset LatexCommand \index{interrupt}
+
+\end_inset
+
+ service routines should not do any of the above operations.
+ If this is unavoidable then the above routines will need to be compiled
+ with the
+\emph on
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+-stack-auto
+\begin_inset LatexCommand \index{-\/-stack-auto}
+
+\end_inset
+
+
+\emph default
+ option, after which the source program will have to be compiled with
+\emph on
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+-int-long-reent
+\begin_inset LatexCommand \index{-\/-int-long-reent}
+
+\end_inset
+
+
+\emph default
+ option.
+ Notice that you don't have to call these routines directly.
+ The compiler will use them automatically every time an integer operation
+ is required.
+
+\layout Section
+Floating Point Support
+\begin_inset LatexCommand \index{Floating point support}
+
+\end_inset
+
+
+
+\layout Standard
+SDCC supports IEEE (single precision 4 bytes) floating point numbers.
+ The floating point support routines are derived from gcc's floatlib.c and
+ consist of the following routines:
+\newline
+
+
+\layout Standard
+\align center
+
+\size footnotesize
+\begin_inset Tabular
+<lyxtabular version="3" rows="17" columns="2">
+<features>
+<column alignment="left" valignment="top" leftline="true" width="0">
+<column alignment="left" valignment="top" leftline="true" rightline="true" width="0">
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+Function
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+Description
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fsadd.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+add floating point numbers
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fssub.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+subtract floating point numbers
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fsdiv.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+divide floating point numbers
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fsmul.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+multiply floating point numbers
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2uchar.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to unsigned char
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2char.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to signed char
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2uint.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to unsigned int
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2int.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to signed int
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2ulong.
+\family default
+\series default
+\shape default
+\size default
+\emph default
+\bar default
+\noun default
+c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to unsigned long
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_fs2long.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert floating point to signed long
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_uchar2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert unsigned char to floating point
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_char2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert char to floating point number
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_uint2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert unsigned int to floating point
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_int2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert int to floating point numbers
+
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_ulong2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert unsigned long to floating point number
+
+\end_inset
+</cell>
+</row>
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+_long2fs.c
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\family roman
+\series medium
+\shape up
+\size normal
+\emph off
+\bar no
+\noun off
+\color none
+convert long to floating point number
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\newline
+
+
+\layout Standard
+\added_space_bottom bigskip
+These support routines are developed in ANSI-C so there is room for space
+ and speed improvement
+\begin_inset Foot
+collapsed false
+
+\layout Standard
+These floating point routines (
+\emph on
+not
+\emph default
+ sinf(), cosf(), ...) for the mcs51 are implemented in assembler.
+
+
+\end_inset
+
+.
+ Note if all these routines are used simultaneously the data space might
+ overflow.
+ For serious floating point usage the large model might be needed.
+ Also notice that you don't have to call this routines directly.
+ The compiler will use them automatically every time a floating point operation
+ is required.
+
+
+
+\layout Section
+Library Routines
+\begin_inset LatexCommand \index{Libraries}
+
+\end_inset
+
+
+
+\layout Standard
+
+\emph on
+<pending: this is messy and incomplete - a little more information is in
+ sdcc/doc/libdoc.txt
+\emph default
+ >
+
+\layout Subsection
+Compiler support routines (_gptrget, _mulint etc.)
+
+\layout Subsection
+Stdclib functions (puts, printf, strcat etc.)
+
+\layout Subsubsection
+<stdio.h>
+
+\layout Paragraph
+getchar(), putchar()
+
+\layout Standard
+\begin_inset LatexCommand \index{<stdio.h>}
+
+\end_inset
+
+As usual on embedded systems you have to provide your own
+\family typewriter
+getchar()
+\begin_inset LatexCommand \index{getchar()}
+
+\end_inset
+
+
+\family default
+and
+\family typewriter
+putchar()
+\begin_inset LatexCommand \index{putchar()}
+
+\end_inset
+
+
+\family default
+ routines.
+ SDCC does not know whether the system connects to a serial line with or
+ without handshake, LCD, keyboard or other device.
+ And whether a
+\family typewriter
+lf
+\family default
+ to
+\family typewriter
+crlf
+\family default
+ conversion within
+\family typewriter
+putchar()
+\family default
+ is intended.
+ You'll find examples for serial routines f.e.
+ in sdcc/device/lib.
+ For the mcs51 this minimalistic polling
+\family typewriter
+putchar()
+\family default
+ routine might be a start:
+
+\layout Verse
+
+\family typewriter
+void putchar (char c) {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+while (!TI)\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ /* assumes UART is initialized */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+TI
+ = 0;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+SBUF = c;
+\newline
+}
+
+\layout Paragraph
+printf()
+
+\layout Standard
+The default
+\family typewriter
+ printf()
+\begin_inset LatexCommand \index{printf()}
+
+\end_inset
+
+
+\family default
+ implementation in
+\family typewriter
+ printf_large.c
+\family default
+ does not support float (except on ds390).
+ To enable this recompile it with the option
+\emph on
+-
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+DUSE_FLOATS=1
+\begin_inset LatexCommand \index{USE\_FLOATS}
+
+\end_inset
+
+
+\emph default
+ on the command line.
+ Use
+\emph on
+ -
+\begin_inset ERT
+status Collapsed
+
+\layout Standard
+
+
+\backslash
+/
+
+\end_inset
+
+-model-large
+\begin_inset LatexCommand \index{-\/-model-large}
+
+\end_inset
+
+
+\emph default
+ for the mcs51 port, since this uses a lot of memory.
+
+\layout Standard
+If you're short on code memory you might want to use
+\family typewriter
+printf_small()
+\begin_inset LatexCommand \index{printf\_small()}
+
+\end_inset
+
+
+\family default
+
+\emph on
+instead
+\emph default
+ of
+\family typewriter
+ printf().
+
+\family default
+ For the mcs51 there additionally are assembly versions
+\family typewriter
+printf_tiny()
+\begin_inset LatexCommand \index{printf\_tiny() (mcs51)}
+
+\end_inset
+
+
+\family default
+ (subset of printf using less than 270 bytes) and
+\family typewriter
+printf_fast()
+\begin_inset LatexCommand \index{printf\_fast() (mcs51)}
+
+\end_inset
+
+
+\family default
+and
+\family typewriter
+ printf_fast_f()
+\begin_inset LatexCommand \index{printf\_fast\_f() (mcs51)}
+
+\end_inset
+
+
+\family default
+ (floating-point aware version of printf_fast) which should fit the requirements
+ of many embedded systems (printf_fast() can be customized by unsetting
+ #defines to
+\emph on
+not
+\emph default
+ support long variables and field widths).
+ Be sure to use only one of these printf options within a project.
+\newline
+
+
+\layout Standard
+Feature matrix of different
+\emph on
+printf
+\emph default
+ options on mcs51.
+
+\layout Standard
+\begin_inset Tabular
+<lyxtabular version="3" rows="14" columns="7">
+<features islongtable="true">
+<column alignment="left" valignment="center" leftline="true" width="14col%">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="12col%">
+<column alignment="center" valignment="top" leftline="true" width="10col%">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="12col%">
+<column alignment="center" valignment="top" rightline="true" width="0">
+<row topline="true" bottomline="true" endhead="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+\series bold
+\size large
+mcs51
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+printf
+\begin_inset LatexCommand \index{printf}
+
+\end_inset
+
+
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+printf
+\size scriptsize
+USE_FLOATS=1
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+printf_small
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+printf_fast
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+