; assembler-programmierung im avr-studio v. atmel
 ; f. die mikroprozessor-Systeme  mega8,-16,-32, ggf. asm entsprechend type abändern!
 ; allg. anweisungen
.NOLIST
.INCLUDE "m32def.inc" ; prozessortype/datei benennen/einfügen dh. hier "mega32", diese Type zuvor auch für den simulator auswählen!

; register umbenennen
.DEF HL=R16
.DEF HH=R17
.DEF KL=R18
.DEF KH=R19

; speicheradr. (ram) mit namen benennen
#define sregister  $5F
#define tempwert   $60 ;$61,62,63
#define tabzaehler $64 ;$65  untere-,obere adr.
#define ergebnis   $66 ;$67  $68/$69
#define summe      $6A ;$6B  $6C/$6D

; befehlsfolge (macro) benennen
.MACRO  Hreg        ; register mit festwert laden (8,8bit)
                ldi R17,@0
                ldi R16,@1
.ENDMACRO

.MACRO Hout      ; register f. ausgabe (8,8bit)
                out @0,R17
                out @1,R16
.ENDMACRO

.MACRO Xload        ; register vom speicher laden (adr.daten 8,8bit)
                lds XH,@0
                lds XL,@1
.ENDMACRO

.MACRO Xkeep        ; register in speicher laden (8,8bit)
                sts @0,XH
                sts @1,XL
.ENDMACRO

.MACRO Xbyte          ; register mit festwert laden (16bit)
                ldi XL,LOW(@0)
                ldi XH,HIGH(@0)
.ENDMACRO

.MACRO Ybyte
                ldi YL,LOW(@0)
                ldi YH,HIGH(@0)
.ENDMACRO

.MACRO Zbyte
                ldi ZL,LOW(@0)
                ldi ZH,HIGH(@0)
.ENDMACRO

.MACRO  Zget                   ; register vom speicher laden (adr.daten 16bit)
                ldi ZL,LOW(@2)
                ldi ZH,HIGH(@2)
                ld @0,Z
                ldi ZL,LOW(@3)
                ldi ZH,HIGH(@3)
                ld @1,Z
.ENDMACRO

.MACRO  Zput         ; register in speicher laden (adr.daten 16bit)
                ldi ZL,LOW(@0)
                ldi ZH,HIGH(@0)
                st Z,@2
                ldi ZL,LOW(@1)
                ldi ZH,HIGH(@1)
                st Z,@3
.ENDMACRO

.MACRO  Zlpm       ; daten vom flash holen (adr.daten 16bit)
                lpm HL,Z+
                lpm HH,Z
.ENDMACRO

; prog. anfang
.cseg
.org 0
nop ; erste adr. im flash
 jmp START

FUNKTION:    ; könnte auch im eeprom stehen u. ins ram kopiert werden
.DW BOXO,DIVI,BOXI,MULTI,BOXO,QWURZI,BOXI,SUBA,BOXO,DIVI
.DW BOXO,BITI,FMULTO,BOXU,WANDLO
.DW BOXO,BITI,ADDI,BOXI,WANDLI
.DW BOXO,ELOGI,BOXO,ELOGI,BOXO,ELOGI,BOXO,ELOGI,BOXO,ELOGI,BOXO,ELOGI
.DW BOXO,NLOGO,BOXO,NLOGO,BOXO,NLOGO,BOXO,NLOGO,BOXO,NLOGO,BOXO,NLOGO
.DW BOXO,MLOGO,BOXO,MLOGO,BOXO,MLOGO,BOXO,MLOGO,BOXO,MLOGO,BOXO,MLOGO,BOXO,MLOGO

DATEN:
.DW $09D8,0x002A,0,0,$E10,0,0,0,$EEEE,$321
.DW 18125,6250,0,0,0 ; 5 stellen f.werte 1,xxxx u.4 stellen f.werte 0,xxx
.DW 6250,6250,0,0,0
.DW 10000,0,7500,0,5000,0,2500,0,1250,0,625,0 ; usw.f.werte 1 0,5 0,2
.DW 27182,0,21170,0,16487,0,12840,0,11331,0,10644,0
.DW 0,14368,0,24368,0,44368,0,64368,$1,$2280,$1,$4990,$1,$70A0 ; x,y= 32bitwert f. x,xxxx
  

; prozesse setzen
.cseg
.org 100
START:
   cli         ; unterbrechung/interupt sperren
   Hreg HIGH(RAMEND),LOW(RAMEND) ; letzte adr des programmzeigers/stackpointer einstellen
   Hout SPH,SPL
   Hreg 0,0
   Zput tempwert+1,tempwert,HH,HL   ; speicherstellen (ram) auf null setzen,
   Zput tabzaehler+1,tabzaehler,HH,HL  ; start adr. f. prog.
   Zput ergebnis+1,ergebnis,HH,HL
   Zput ergebnis+3,ergebnis+2,HH,HL
   Zput summe+1,summe,HH,HL
   movw XL,HL  ; falls neustart
   bclr 6       ; t-bit löschen f.unsig./o.vorzeichen

; hauptprog. ausführen
PROG:
   Ybyte(FUNKTION*2)   ; adr. tabelle laden
   rcall ADDI
   movw ZL,XL      ; adr. in Z bereitstellen
   Zlpm       ; inhalt der adr. laden
   movw XL,R18   ; werte einstellen
   movw YL,R20
   movw ZL,HL
   icall                      ; nächstes prog. aus tab. aufrufen
   Zput ergebnis+1,ergebnis,XH,XL   ; werte in den speicher ablegen
   Zput ergebnis+3,ergebnis+2,YH,YL
   Xload tabzaehler+1,tabzaehler   ; prog.- od. tastencode laden
   adiw XH:XL,2                      ; nächste adr.
   Xkeep tabzaehler+1,tabzaehler  ; aufheben
   jmp PROG

; unterprog.
BOXO:                 ; rechenwerte aus tab. "daten" holen
   Ybyte(DATEN*2)
   Xload tabzaehler+1,tabzaehler
   rcall ADDI
   movw ZL,XL
   Zlpm
   movw R18,HL
   adiw ZH:ZL,1
   Zlpm
   movw R20,HL
   ret

BOXI:           ; werte aus dem speicher laden
   Zget R19,R18,ergebnis+1,ergebnis
   Zget R21,R20,ergebnis+3,ergebnis+2
   ret

BOXU:           ; werte aus dem speicher laden
   Zget R21,R20,ergebnis+1,ergebnis
   Zget R19,R18,ergebnis+3,ergebnis+2
 ret

BITI:
   rcall WANDLA
   movw R18,XL    ; werte einstellen
   movw XL,R16
   rcall WANDLA
   movw R20,XL
   ret

WANDLA:         ; bitwandler(num2fnum) x=>x
   ldi R16,8-1    ;umrechenwert= wert * 0x80 / 0x2710
   mov R5,R16     ; schleifenzähler
   eor R6,R6    ; reg. null setzen
   movw R16,YL
   Ybyte(10000)  ; festwert
   movw R2,YL
WANDLA_LOOP1:
   movw YL,XL    ; teste
   movw XL,R2
   rcall SUBA
   rol R6      ; carry holen
   or XL,XH
   brne WANDLA_LOOP2
   inc R6
   rjmp WANDLA_FIN
WANDLA_LOOP2:
   movw XL,YL
   movw YL,R2   ; festwert
   sbrc R6,0
   rcall SUBA   ; berechne rest
   rol XL     ; wert *2
   rol XH
   dec R5       ;schleifenzähler-1
   brne WANDLA_LOOP1
   rol R6
   rjmp WANDLA_END
WANDLA_FIN:
   clc
   rol R6
   dec R5
   brne WANDLA_FIN
WANDLA_END:
   movw XL,R6  ; einstellen
   ret

WANDLU:         ; bitwandler(num2fnum) x,y=>x
   ldi R16,16-1  ; umrechnenwert= (wert*0x8000)/0x2710
   mov R5,R16     ; schleifenzähler
   clr R4         ; allg. hilfreg.
   clr R6       ; reg. null setzen
   clr R7
   inc R4
   movw R8,YL    ; 32bit wert
   movw R10,XL
   Ybyte($2710)  ; festwert(10tsd)
   Xbyte($0000)
   movw R2,YL
   movw R0,XL
WANDLU_LOOP1:
   movw XL,R0
   movw YL,R2
   sub XL,R8    ; festwert
   sbc XH,R9
   sbc YL,R10
   sbc YH,R11
   rol R6      ; carry holen
   rol R7
   or XL,XH
   or XL,YL
   or XL,YH
   brne WANDLU_LOOP2
   add R6,R4
   clr R4
   adc R7,R4
   inc R4
   rjmp WANDLU_FIN
WANDLU_LOOP2:
   movw XL,R8      ; festwert
   movw YL,R10      ; restwert
   sbrs R6,0
   rjmp WANDLU_LOOP3
   sub XL,R0
   sbc XH,R1
   sbc YL,R2
   sbc YH,R3
WANDLU_LOOP3:
   rol XL      ; wert *2
   rol XH
   rol YL
   rol YH
   movw R8,XL
   movw R10,YL
   dec R5       ;schleifenzähler
   brne WANDLU_LOOP1
   rol R6
   rol R7
   rjmp WANDLU_END
WANDLU_FIN:
   clc
   rol R6
   rol R7
   dec R5
   brne WANDLU_FIN
WANDLU_END:
   movw XL,R6  ; einstellen
   ret

WANDLI:       ; bitwandler(fnum2num) xl=>x
   mov R6,XL
   eor XL,XL        ;null setzen
   eor XH,XH
   ldi R16,8-1
   mov R5,R16 ; schleifenzähler
   movw R16,YL
   Ybyte(10000)  ; festwert
WANDLI_LOOP:
   sbrc R6,7
   call ADDI   ; teilwert
   clc
   ror YH     ; festwert
   ror YL
   clc
   rol R6
   dec R5
   brne WANDLI_LOOP
   ret

WANDLO:            ; bitwandler(fnum2num) x=>x,y
   movw R6,XL       ; umrechnenwert=(wert*2*0x2710)/0x10000  ,bei neg.wert abzügl. 20tsd.
   ldi R16,16-1    ; bsp. 0xB000 ergibt nach wandelo 0x35B6(13750) davon 20tsd=>-0,625
   mov R5,R16    ; schleifenzähler
   movw R16,YL
   Ybyte($2710)  ; festwert (10tsd)
   Xbyte($0000)
   movw R2,YL
   movw R0,XL
   Xbyte(0)
   Ybyte(0)
WANDLO_LOOP1:
   sbrs R7,7
   rjmp WANDLO_LOOP2
   clc
   add YL,R0
   adc YH,R1
   adc XL,R2
   adc XH,R3
WANDLO_LOOP2:
   clc
   ror R3     ; festwert
   ror R2
   ror R1
   ror R0
   clc
   rol R6
   rol R7
   dec R5
   brne WANDLO_LOOP1
   ret

SUBA:        ; subtraktion x-y=x
   clc
   sub XL,YL
   sbc XH,YH
   ret

ADDI:      ; addition x+y=x
   clc
   add XL,YL
   adc XH,YH
   ret

DIVI:            ; division  x/y=x
   ldi R17,16+1  ; schleifenzähler
   clr R16     ; ereignis behalten
   clr R0      ; hilfsregister
   clr R1
   clr R2      ;  zwischenregister
   clr R3
   neg YL     ; divisor 2er komplement bilden bzw.jedes bit umkehren +1)
   adc YH,R16  ; übernehme  carry
   neg YH
DIVI_LOOP1:
   mov R0,R2    ; zwischenergebnis behalten
   mov R1,R3
   add R2,YL   ; divisor subtrahieren bzw. 2er komplement addieren
   adc R3,YH
   brcs DIVI_LOOP2
   mov R2,R0     ; zwischenergebnis wiederherstellen
   mov R3,R1
DIVI_LOOP2:
   rol XL  ; nächste stelle holen vom dividenten
   rol XH
   rol R2   ; einlesen in zwischenspeicher
   rol R3
   dec R17  ; schleifenzähler abwärts
   brne DIVI_LOOP1
   neg YL    ; beenden, divisor wiederherstellen
   adc YH,R17  ; hinzu carry
   neg YH
   or R16,XL   ; teste ergebnis auf null
   or R16,XH
   brne DIVI_LOOP3
   clc
   ror R3   ; zwischenspeicher wieder herstellen
   ror R2
DIVI_LOOP3:
   ret

DIVO:            ;  division  x,y/r1,r0=x,y (erweiterte struktur von divi)
   ldi R17,32+1  ; schleifenzähler
   clr R16     ; ereignis behalten
   clr R2      ; hilfsregister r2,3,4,5
   clr R3
   clr R4
   clr R5
   clr R6    ;  zwischenregister r6,7,8,9
   clr R7
   clr R8
   clr R9
   neg R0     ;  2er komplement bilden
   adc R1,R16  ;  carry
   neg R1
DIVO_LOOP1:
   movw R2,R6    ; zwischenergebnis
   movw R4,R8
   com R16
   add R6,R0    ; hinzu 2er komplement
   adc R7,R1
   adc R8,R16 ; schiebe carry
   adc R9,R16
   brcs DIVO_LOOP2
   movw R6,R2  ; zwischenergebnis wiederherstellen
   movw R8,R4
DIVO_LOOP2:
   clr R16
   rol YL  ; nächste stelle
   rol YH
   rol XL
   rol XH
   rol R6   ; zwischenspeicher
   rol R7
   rol R8
   rol R9
   dec R17  ; zähler
   brne DIVO_LOOP1
   neg R0    ;  wiederherstellen
   adc R1,R17  ; hinzu carry
   neg R1
   or R16,YL   ; teste
   or R16,YH
   or R16,XL
   or R16,XH
   brne DIVO_LOOP3
   clc
   ror R9   ; zwischenspeicher
   ror R8
   ror R7
   ror R6
DIVO_LOOP3:
   ret

MULTI:      ; multiplikation x*yl=x
   clc
   clr R3
   clr R2
   ldi R16,8       ; schleifenzähler
MULTI_LOOP1:
   ror R3        ; schiebe resultat
   ror R2
   dec R16
   brlt MULTI_EXIT
   ror XL            ; schiebe multiplikant
   brcc MULTI_LOOP1  ;    übertrag ?
   add R3,YL              ; addiere multiplikator zum resultat
   rjmp MULTI_LOOP1      ; wiederhole
MULTI_EXIT:
   movw XL,R2
   ret

MULTA:         ; multiplikation x*yl=xl,y
   mov KL,YL    ; t-bit f. unsig/sig
   movw HL,XL
   clr XH      ; hilfsreg.
   lds R2,sregister
   sbrs R2,6
   mul HH,KL    ; xh*yl
   sbrc R2,6
   muls HH,KL    ; sig,xh*sig.yl
   mov YH,R0
   mov XL,R1
   sbrs R2,6
   mul KL,HL     ; yl*xl
   sbrc R2,6
   mulsu KL,HL   ; sig.yl*xl
   sbrc R2,6
   sbc XL,XH
   mov YL,R0
   add YH,R1
   adc XL,XH
   ret        ;  ergb. in xl,y

MULTO:          ; multiplikation x*y=x,y
   movw HL,YL    ; t-bit f. unsig/sig
   movw KL,XL
   clr R2       ; hilfsreg.
   lds R3,sregister
   sbrs R3,6
   mul KH,HH      ; xh*yh
   sbrc R3,6
   muls KH,HH    ; sig.xh*sig.yh
   movw XL,R0
   mul KL,HL     ;  xl*yl
   movw YL,R0
   sbrs R3,6
   mul KH,HL     ; xh*yl
   sbrc R3,6
   mulsu KH,HL   ; sign.xh*yl
   sbrc R3,6
   sbc XH,R2
   add YH,R0     ; summe bilden
   adc XL,R1     ; carry hinzu
   adc XH,R2
   sbrs R3,6
   mul HH,KL    ; yh*xl
   sbrc R3,6
   mulsu HH,KL   ; sig.yh*xl
   sbrc R3,6
   sbc XH,R2
   add YH,R0
   adc XL,R1
   adc XH,R2    ; ergeb. x,y
   ret

FMULTA:
   mov HH,XL      ;fraktionalnummer xl*yl=>x
   mov HL,YL       ;  t-bit f. unsig./sig.
   lds R2,sregister
   sbrs R2,6
   fmul HH,HL    ; xl * yl
   sbrc R2,6
   fmuls HH,HL  ; sig.xl * sig.yl
   movw XL,R0
   ret

FMULTO:         ;fraktionalnummer(bruchrechnen) x*y=x,y
   movw HL,YL    ; t-bit f. unsig/sig
   movw KL,XL
   clr R2
   lds R3,sregister
   sbrs R3,6
   fmul KH,HH  ; xh*yh  od.
   sbrc R3,6
   fmuls KH,HH  ; rechne sig.xh*sig.yh <1
   movw XL,R0
   fmul KL,HL     ; rechne xl*yl
   adc XL,R2
   adc XH,R2
   movw YL,R0
   adc XL,R2
   adc XH,R2
   sbrs R3,6
   fmul KH,HL  ; xh*yl  od.
   sbrc R3,6
   fmulsu KH,HL  ; rechne sig.xh*yl <1
   sbrs R3,6
   sbc XH,R2
   add YH,R0
   adc XL,R1
   adc XH,R2
   sbrs R3,6
   fmul HH,KL     ; yh*xl od.
   sbrc R3,6
   fmulsu HH,KL  ; rechne sig.yh*xl <1
   sbrs R3,6
   sbc XH,R2
   add YH,R0
   adc XL,R1
   adc XH,R2
   ret          ; ergb. x,y

QWURZI:            ; quadratwurzel(x)=>x   (ganzzahlig)
   movw YL,XL
   movw R4,XL
   ldi R22,16-2   ; schleifenzähler
QWURZI_GATE1:
   rcall DIVI
   rcall ADDI      ; zum ergebnis hinzu
   clc
   ror XH        ;  wert halbieren mit carry
   ror XL
   movw YL,XL     ; neuer wert
   movw XL,R4
   dec R22
   brne QWURZI_GATE1
   movw XL,YL     ; ergeb. in x
   ret

ELOGI:          ;  exponentialfunktion  e(x)=>x  f.<1  (ganzzahlig gemäß euler)
   Ybyte(0)      ;  bspw. sei x=1,7   umrechenwert=(e x/2)q2
   rcall WANDLU     ; kehrwert bilden, dh, wertigkeit der bits ist umgekehrt
   Ybyte(0)
   Zbyte(10000)        ; 1/fakultät(n)
   movw R10,ZL   ; abzügl. f.kofa hilfsregister
   movw ZL,YL     ; summenwert null setzen
   Ybyte($0908)       ; schleifenzähler f. 1/fakultät
   movw R12,YL
   movw R6,XL
   movw R8,XL        ; kehrwert(xn) in mul stelle ablegen
ELOGI_TOUR:
   rcall KOFA
   dec R12
   breq ELOGI_DONE
   clc
   rol XL         ; (1/!) *2
   rol XH        ; umrechnen
   movw YL,R8   ; einstellen
   rcall MULTO     ; ergebnis in x
   movw YL,ZL
   rcall ADDI       ; summenwert bilden
   movw ZL,XL
   movw XL,R8   ; xn-wert
   movw YL,R6    ; rechne xn *x bilden
   rcall FMULTO
   movw R8,XL   ; oberwert in mul stelle ablegen
   rjmp ELOGI_TOUR
ELOGI_DONE:
   movw XL,ZL    ; summenwert
   Ybyte(10000) ; hinzu ergb.
   rcall ADDI
   ret          ; erg. in x

KOFA:              ; 1/n!=x   n=r15-r14
    Xbyte(10000)  ; die hier berechneten werte könnten auch in tab. stehen
   movw YL,R10   ; hilfsregister
   rcall DIVI
   clr YH
   mov YL,R13
   sub YL,R12
   rcall MULTA
   Xbyte(10000)
   rcall DIVI
   movw R10,XL   ; teste restwert
   movw XL,R2     ; hole restwert aus divi (r3,r2)
   ldi XL,2   ; hunderstel
   subi XH,13   ; abzügl.
   brlo KOFA_BYE
   add R10,XL     ; ansonsten hinzu
   eor XL,XL   ; null setzen
   adc R11,XL   ; übernehme ergebnis
KOFA_BYE:
   movw XL,R10   ; übernehme ergebnis
   ret

NLOGO:   ; logarithmus ln(x)=>x  wobei  x<2,7182  (mittels taylor-reihe)
 .EQU k_nlogo=4  ;   bsp.  x=5  dann ist d. umrechenwert=ln(5/2)+ln(2)
   clr ZH         ;    f. den divisor kann man sich d. ln(1 b.5) bspw. in tab.  notieren
   clr ZL          ; summe
   Ybyte($0B0A)  ; schleifenzähler
   movw R12,YL     ; aufheben
   movw R14,XL     ; rechenwert ebenfalls aufheben
   Ybyte(10000)  ; abzügl.10tsd (f. wert 1)
   rcall SUBA     ; x-y=x, subiw setzt ggf. kennzeichen S
   cls         ; neg. kennzeichen löschen d.h. rechnen nur mit pos.Zahlen
   breq NLOGO_END
   brsh NLOGO_NEXT1       ; bei neg.wert status C gesetzt
   ses                           ; neg. kennzeichen setzen ggf.wert umwandeln in 2er kompl.f.neg.Zahl
   movw YL,R14
   Xbyte(10000)       ; abzügl.10k
   rcall SUBA       ; mit subiw würde Kennzeichen S verändert
NLOGO_NEXT1:
   movw R22,XL   ; ergeb. suba f. zähler aufheben
   movw XL,R14       ; rechenwert erneut laden
   Ybyte(10000)  ; hinzu wert 10tsd.
   rcall ADDI
   movw R14,XL  ; nenner behalten
   movw XL,R22       ; zähler laden
   Ybyte(k_nlogo)
   rcall DIVI
   Ybyte(0)
   rcall WANDLU ; kehrwert bilden
   movw R22,XL  ; neuen zähler aufheben
   movw R24,XL  ; ebenso in mul.stelle ablegen
   movw XL,R14       ; nenner holen
   Ybyte(k_nlogo)       ; ebenfalls um faktor verkeinern
   rcall DIVI
   Ybyte(0)
   rcall WANDLU       ; vom nenner auch kehrwert bilden
   movw R14,XL ; neuen nenner aufheben
   movw R20,XL  ; ebenso in mul.stelle ablegen
NLOGO_NEXT2:
   rcall KOWE  ; berechne 1/n
   movw YL,R24       ; zähler aus mul.stelle holen
   rcall MULTO       ; ldf.zähler mul. mit kehrwert (multo liefert 32bitwert x,y)
   movw R0,R20       ; divident nach r1,r0 f. divo
   rcall DIVO
   movw XL,ZL  ; davon summe bilden
   rcall ADDI
   movw ZL,XL
   movw XL,R22  ; potenz des zählers bilden
   movw YL,R24       ; zähler aus mul.stelle holen
   rcall FMULTO
   movw YL,R22        ; nochmal
   rcall FMULTO
   movw R24,XL  ; potenzwert des zähler nach mull. stelle
   movw XL,R14       ; neuen nenner holen
   movw YL,R20   ; nenner aus mul.stelle holen
   rcall FMULTO
   movw YL,R14       ; nochmal da potenzwert um 2 steigt
   rcall FMULTO
   movw R20,XL  ; in mull stelle ablegen
   mov XL,R12  ; ldf.zähler ende ?
   subi XL,3
   brsh NLOGO_NEXT2       ; bei neg.wert od. gleich weiter ansonsten nach
   clc
   movw XL,ZL
   rol XL   ; letztlich *2
   rol XH
NLOGO_END:
   ret

KOWE:         ;  x=1/1  ,3,5,7
   mov YL,R13
   sub YL,R12
   Xbyte(10000)
   clr YH
   rcall DIVI
   dec R12   ; neuen ldf.zähler bilden
   dec R12
   ret

mLOGO:   ; ln(x,y)=>x wobei ergeb. x>1
  Zbyte(10000)  ; bilde sprungwert
  movw R0,ZL
  rcall DIVO
  mov R24,YL  ; ermittelten wert aufheben
  movw XL,R18  ; wert aus Boxo nachladen
  movw YL,R20
  or R24,R24  ; ereignis setzen
  breq mLOGO_0  ; wert <2
  dec R24
  cpi R24,1
  brcs mLOGO_1
  cpi R24,2
  brcs mLOGO_2
  cpi R24,3
  brcs mLOGO_2
  cpi R24,4
  brcs mLOGO_2
  rcall mLOGO_3
  ret
  
mLOGO_0:
  movw XL,YL  ; für werte 0,xxxx bis 1
  rcall nlogo
  ret
mLOGO_1:  ; für werte 1,xxxx bis 2
  eor R25,R25
  ldi R24,2
  movw R0,R24
  rcall DIVO
  movw XL,YL
  rcall NLOGO  ; da t-bit gesetzt
  movw YL,XL
  XByte(6931)  ; ln(2)
  rcall SUBA
  ret
mLOGO_2:
  eor R25,R25  ; für werte 2,xxxx bis 4,xxxx
  ldi R24,2
  movw R0,R24
  rcall DIVO
  movw XL,YL
  rcall NLOGO
  YByte(6931)  ; ln(2) hinzu
  rcall ADDI
  ret
mLOGO_3:
  eor R25,R25  ; für werte 5,xxxx bis 9,xxxx
  ldi R24,4
  movw R0,R24
  rcall DIVO
  movw XL,YL
  rcall NLOGO
  YByte(2*6931)  ; 2*ln(2) hinzu
  rcall ADDI
  ret
  

; ------------- ende ----------

Quellen:Siemens(Assembler8080),Motorola(MC68000),Atmel(App.Notes)

K. Moosbauer
Techniker f. MSR                               erstellt: Jan.'09,erneuert,ergänzt: Mai'19 erweitert:Juni'19