Das Open-Control-Projekt - Die Alternative zur C-Control-I


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Re: Quadratwurzel von 32 Bit Zahl Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von GeKue - 23.12.2014 20:10)
 Als Antwort auf Re: Quadratwurzel von 32 Bit Zahl von Joe - 20.12.2014 22:43
Hallo Joe,

war zu faul das elm-chan - Programm umzusetzen.
Habe es deshalb neu geschrieben, auf der Grundlage des schriftlichen Wurzelziehens. Komme aber erst im neuen Jahr dazu es auf die OM zu bringen. Für die OM-Micro können natürlich Speicher noch mittels
Stapel gespart werden, bzw. das Ergebnis in den leer werdenden 32-Bit-Zahl Speicher gelegt werden.
Mit wenigen Programmschritten (ohne weitere Speichernutzung) ließen sich natürlich auch noch bis zu 6Bit - Nachkommawerte für evt. Rundungen berechnen.
Hier der Quellcode mit "Code-Warrior" simuliert und mit Erklärung versehen.
Kommst Du damit nicht klar, bringe ich es selbst noch auf die OM und schicke sowieso noch eine ausführlichere Erklärung an Dietmar - aber erst die zwote Januarwoche....

Beste Grüße, GeKue

**************
            ASMB1a: DC.B 1           'hier steckt die 32-Bit-zahl drin
            ASMB1b: DC.B 1
            ASMB1c: DC.B 1
            ASMB1d: DC.B 1
            Sub1a1: DC.B 1
            Sub1a:  DC.B 1
            Sub1b:  DC.B 1
            Res1a1: DC.B 1
            Res1a:  DC.B 1            ' in Res1a und Res1b
            Res1b:  DC.B 1            ' wird das Ergebnis ausgegeben

mainLoop:
            ; Hier die 32-Bitzahl eintragen und notwendige Startwerte vergeben
            MOV  #0,ASMB1d  ; hier statt Null x-beliebige Werte vergeben
            MOV  #0,ASMB1c  ; aus denen die Wurzel gezogen werden soll
            MOV  #0,ASMB1b
            MOV  #0,ASMB1a  ;höherwertiges Byte des 32-Bit-Wertes
            MOV  #1,Res1b   ; Startwert muß auf 1 gesetzt werden
            MOV  #0,Res1a
            MOV  #0,Res1a1  
            MOV  #0,Sub1b
            MOV  #0,Sub1a
            MOV  #0,Sub1a1  
            LDX  #16        ;Schleifenzähler muß auf 16 stehen
           
         ; Suchen des ZahlenAnfangs durch Links-Schieben          
           Find_Start:
            JSR Schieb
            DECX
            LDA Sub1b
            CBEQA #0,Find_Start            
          ;StartWert
            SUB #1     ;Erste Differenz nach A
            STA Sub1b  ; Differenz in Sub1b
          Loop:        ; rechnet zu Fuß mit binomischer Formel  
            JSR Schieb ; Zwei Bits herunterholen und nach Sub1 schieben        
            ASL Res1b  ; Subtrahent mit 4
            ROL Res1a  ; multiplizieren
            ROL Res1a1
            SEC        ; und mit 1 erweitern
            ROL Res1b
            ROL Res1a
            ROL Res1a1
            PSHX       ; X retten = Schiebezähler
            LDHX Res1a1
            CPHX Sub1a1
            BHI NoSubtrak  ; wenn Res1a>als Subtrak
            BEQ NewTest    ; wenn beide Werte gleich, neu testen
          Subtrak:
            LDA Sub1a1       ; Subtraktion Sub1-Res1 - Ergebnis nach Sub1
            SUB Res1a1
            STA Sub1a1
            LDA Sub1a      
            SBC Res1a
            STA Sub1a
            LDA Sub1b
            SBC Res1b
            STA Sub1b
            BSET 1,Res1b    ;1 als neue Ziffer setzen
          NoSubtrak:
            LSR Res1a1      ; Result regenerieren
            ROR Res1a
            ROR Res1b
            PULX
            DBNZX Loop
            NOP             ; jetzt steht das Ergebnis in Res1a und Res1b          
     
          NewTest:
            LDA Res1b
            CMP Sub1b
            BHI NoSubtrak
            BRA Subtrak
         
            Schieb:
            JSR Schieb1
            Schieb1:
            ASL ASMB1d
            ROL ASMB1c
            ROL ASMB1b
            ROL ASMB1a
            ROL Sub1b
            ROL Sub1a
            ROL Sub1a1
            RTS

*******************************



> Hallo GeKue,
>
> heute habe ich versucht den Programm Code zu schreiben. So wie Du schon vorher gesehen hast, habe ich dann bei der Anpassung einiger ASM-Befehle (brpl, ldi, rjmp, andi, ori,sbrc, subi) an den Befehlssatz des OM-Assemblers Probleme bekommen.
> Ich hab versucht möglichst wenig von der Vorlage "http://elm-chan.org/docs/avrlib/sqrt32.txt" zu ändern, komme aber nun nicht mehr weiter, da ich bei einigen dieser ASS Befehle nicht dahinter komme, wie man das zum laufen bekommt.
> Vielleicht hast Du mal Zeit meinen Entwurf durch zu sehen u. findest dann eine Lösung. Da ja nun die letzten Vorbereitungen auf Weihnachten sind, eilt es bei diesem Thema überhaupt nicht.
>
> Ein Frohes und besinnliches Weihnachten u. Glück, Gesundheit und Erfolg im Neuen Jahr wünsche ich Dir und allen OM-Freunden
>
> Joe
> ################
> ' 32BSQR1.BAS vom Sa. 20.12.2014
> '
> ' fr den sqrt Ansatz wurd die Loesung von http://elm-chan.org/docs/avrlib/sqrt32.txt
> ' benutzt
> ' Size  = 53 words
> ' Clock = 528..544 cycles (+ret)
> ' Stack = 0 byte
>
> ' Zahlenwertebereich der 32 bit Arithmetik
> ' Dezimal 127     255     255     255
> ' 32-Bit-Zahl $007f       00ff    00ff    00ff dezimal ausgeben: 2147483647
> ' Dezimal 128     255     255     255
> ' 32-Bit-Zahl $0080       00ff    00ff    00ff dezimal ausgeben: -2130706433  
>
> ' ---------------------------------------------------------------------------
> ' --- Betriebssystem konfigurieren ------------------------------------------
> INCLUDE "OMAC.DEF"           'Include-Datei mit Definitionen vom April 2010
>
>
> ' ---------------------------------------------------------------------------
> ' --- Definitionen Variable fuer das Hauptprogramm
> ' ----Def. LONGD Variable umfasst 4 Bytes fuer 32 Bit-----------------------
> '  Register Variables
> '  Call:  var[03:00] = Source (32bit)
> '         var[12:04] =       *var08 and var12 must be high-regs.
> '  Result:var[01:00] = Result (16bit)
> '         var[12:02] =
> DEFINE var_s  AS LONG  '32 Bit Eingabe Wert
> DEFINE var_s3 AS BYTE[4] OF var_s  'MSB  
> DEFINE var_s2 AS BYTE[3] OF var_s  '
> DEFINE var_s1 AS BYTE[2] OF var_s  '     hier Ergebnis High Byte
> DEFINE var_s0 AS BYTE[1] OF var_s  'LSB; hier Ergebnis Low Byte
>
> DEFINE var_wa AS LONG   ' 32Bit Rechenbereich 1= wa
> DEFINE var_wa7 AS BYTE[4] OF var_wa ' MSB
> DEFINE var_wa6 AS BYTE[3] OF var_wa
> DEFINE var_wa5 AS BYTE[2] OF var_wa
> DEFINE var_wa4 AS BYTE[1] OF var_wa ' LSB
>
> ' var[12:04] =       *var08 and var12 must be high-regs.
> ' ???? was bedeutet da bei 08 u. 12 high-register???
> ' muestte das nicht so wie bei var04 bis 07 aufgebaut sein??
> ' oder sollte da register 27,29 oder 31 = high byte register von X, Y Z benutzt werden
> DEFINE var_wb   AS LONG   ' 32 Bit Rechenbereich 2 = wb
> DEFINE var_wb11 AS BYTE[4] OF var_wb ' HSB
> DEFINE var_wb10 AS BYTE[3] OF var_wb
> DEFINE var_wb9  AS BYTE[2] OF var_wb
> DEFINE var_wb8  AS BYTE[1] OF var_wb ' LSB
>
> ' was ist da zu tun bez. high register??
> DEFINE var_wc12    BYTE   ' 9-tes byte des Rechenbereiches
>
>
> ' Hauptprogramm-----------------------------------------------
>
> ' ---------------------------------------------------------------------------
>
> ' --- Beispiel: Quadrat Wurzel
> var_s3=&h00     ' Eingabewerte
> var_s2=&h0F     ' 1 000 000 in Hex = =F 42 40
> var_s1=&h42
> var_s0=&h40
>
>
> PRINT  "SQRT_Ber"
> PRINTHEX=ON
> PRINT var_s3,var_s2,var_s1,var_s0
> PRINTHEX=OFF
> PRINT "SQRT_Erg"
> sqrt_32
> PRINTHEX=ON
> PRINT var_s1,var_s0
> PRINTHEX=OFF
>
> END
>
> ' Subroutine//Procedure fuer Wurzel//Square root aus 32-Bit Zahl
> ' ----------------------------------------------------------------------------:
> PROC sqrt_32 INLASM
> ! clr var_wa4
> ! clr var_wa5
> ! clr var_wa6
> ! clr var_wa7
> '! ldi var08,1 'statt ldi loads konstante 1 in var08
> ! lda var_wb8     ' accu mit var 8 laden
> ! add &H01        ' zu accu den wert 1=H01=&B 0000 0001 addieren
> ! sta var_wb8     ' Ergebnis accu in var_8 gespeichert
> ! clr var_wb9
> ! clr var_wb10
> ! clr var_wb11
> ' ! ldi var12,16
> ! lda var_wc12     ' accu mit var 12 laden
> ! add &H10        ' zu accu den wert 16=H10= B 0001 0000 addieren
> ! sta var_wc12     ' Ergebnis accu in var_12 gespeichert
>
> #sqrt32l
> ! lsl var_s0
> ! rol var_s1
> ! rol var_s2
> ! rol var_s3
> ! rol var_wa4
> ! rol var_wa5
> ! rol var_wa6
> ! rol var_wa7
> ! lsl var_s0
> ! rol var_s1
> ! rol var_s2
> ! rol var_s3
> ! rol var_wa4
> ! rol var_wa5
> ! rol var_wa6
> ! rol var_wa7
> '! brpl PC+6 branch if plus; N bit von status register wird geprueft;
> ' wenn N bit cleared, dann verzweigt der programmcounter zu PC+6
> ' bei OM muesste CCR register bit N da benutzt werden; wohin man aber
> ' da springen soll ist mir unklar
> ' unklar welcher OM Befehl hier passt
> ! bpl spr_0
>
> '! add var04,var08
> ! lda var_wa4     ' accu mit var 4 laden
> ! add var_wb8     ' zu accu die var 8 addieren
> ! sta var_wa4     ' Ergebnis accu in var_4 gespeichert
> '! adc var_wa5,var_wb9
> ! lda var_wa5     ' accu mit var 5 laden
> ! adc var_wb9     ' zu accu die var 9 addieren
> ! sta var_wa5     ' Ergebnis accu in var_5 gespeichert
> '! adc var_wa6,var_wb10
> ! lda var_wa6     ' accu mit var 6 laden
> ! adc var_wb10     ' zu accu die var 10 addieren
> ! sta var_wa6     ' Ergebnis accu in var_6 gespeichert
> '! adc var_wa7,var_wb11
> ! lda var_wa7     ' accu mit var 7 laden
> ! adc var_wb11     ' zu accu die var 11 addieren
> ! sta var_wa7     ' Ergebnis accu in var 7 gespeichert
>
> '! rjmp PC+5  relative jump to an address;
> ' springt hier im programm counter auf PC+5 == lsl var08
> ' von was aber ist der Sprung abhaengig??
> ! jmp Sp_1        ' ist vermutlich falsch
> #spr_0
> '! sub var_wa4,var_wb8
> ! lda var_wa4     'accu mit var 4 laden
> ! sub var_wb8     'von accu die var 8 subtrahieren
> ! sta var_wa4     ' Ergebnis in var 4 gespeichert
> '! sbc var_wa5,var_wb9
> ! lda var_wa5     'accu mit var 5 laden
> ! sbc var_wb9     'von accu die var 9 subtrahieren mit carry bit
> ! sta var_wa5     ' Ergebnis in var 5 gespeichert
> ' sbc var_wa6,var_wb10
> ! lda var_wa6     'accu mit var 6 laden
> ! sbc var_wb10     'von accu die var 10 subtrahieren mit carry bit
> ! sta var_wa6     ' Ergebnis in var 6 gespeichert
> ' sbc var_wa7,var_wb11
> ! lda var_wa7     'accu mit var 7 laden
> ! sbc var_wb11     'von accu die var 11 subtrahieren mit carry bit
> ! sta var_wa7     ' Ergebnis in var 7 gespeichert
> #Sp_1
> ! lsl var_wb8
> ! rol var_wb9
> ! rol var_wb10
> '! andi var08,0b11111000 '1111 1000 = f8 = 248;
> '   andi = and_immediate var08 mit konstanten wert ;
> ' bei OM realisieren mit AND
> ! lda var_wb8     ' accu mit var 8 laden
> ! and #248        ' &hfa=1111 1000; macht logic and im accu
> ! sta var_wb8     ' ergebnis in var 8 gespeichert
>
> '! ori var08,0b00000101= ;&H05==05 logical OR with immidiate;
> '   macht logic OR zwischen var 8 und konstante
> ! lda var_wb8    ' accu mit var 8 laden
> ! or #5          ' Wert 5 vergleichen mit accu; CCR BIt V, N, Z beeinflusst
> ! sta var_wb8    ' ergebnis in var 8 gespeichert; ev. kann dies aber entfallen
>
> '! sbrc var07,7  ' skip//springe if bit 7 in in register var 7 is cleared;
> '   ueberspringt den naechsten Befehl, wenn bit 7 is cleared, falls nicht cleared
> '   wird der naechste befehl subi var08,2 ausgefuehrt
>
> ! brclr 7,var_wb7,spr_2  ' spr_2 'ueberspringt subi ??
>
> '! subi var08,2   'subtrahiert sofort von var 8 den Wert 2=&h02=&b0000 0010
> ! lda var_wb8       ' accu mit var 8 laden
> ! sub #2            ' subtrahiert 2 von accu
> ! sta var_wb8       ' ergebnis von accu in var 8 gespeichert
> #spr_2
> ! dec var_wc12
> '! brne sqrt32l  '
> ' Conditional relative branch. Tests the Zero flag (Z) and branches relatively
> ' to PC if Z is cleared. If the instruction is executed immediately after any
> '  of the instructions CP, CPI, SUB or SUBI, the branch will occur if and
> '  only if the unsigned or signed binary number represented in Rd
> '  was not equal to the unsigned or signed binary number represented
> '  in Rr. This instruction branches relatively to PC in either direction
> ' (PC - 63 = destination = PC + 64). The parameter k is the offset from PC
> '  and is represented in two's complement form.
> '  (Equivalent to instruction BRBC 1,k).
> ! bne sqrt32l     ' verzweigt, wenn bei subtraktion werte var_wb8 und #2 ungleich waren        
>
> ! lsr var_wb10
> ! ror var_wb9
> ! ror var_wb8
> ! lsr var_wb10
> ! ror var_wb9
> ! ror var_wb8
> ! mov var_s0,var_wb8 'var 8 wert in var 0 verschoben; Ergebnis Low byte
> ! mov var_s1,var_wb9 ' Ergebnis High byte
> ! rts             'rts statt ret
>
> END PROC
>
> ' ---------------------------------------------------------------------------
>
> INCLUDE "OM_FW.PRO"

 Antwort schreiben

Bisherige Antworten:

Re: Quadratwurzel von 32 Bit Zahl (von Joe - 28.12.2014 14:48)
    Re: Quadratwurzel von 32 Bit Zahl (von GeKue - 30.12.2014 19:47)
        Re: Quadratwurzel von 32 Bit Zahl (von Joe - 31.12.2014 17:46)
            Re: Quadratwurzel von 32 Bit Zahl (von GeKue - 7.01.2015 15:15)
                Re: Quadratwurzel von 32 Bit Zahl (von Joe - 9.01.2015 9:53)
                    Re: Quadratwurzel von 32 Bit Zahl (von GeKue - 29.01.2015 12:39)
                       Re: Quadratwurzel von 32 Bit Zahl (von Joe - 31.01.2015 15:35)
                          Re: Quadratwurzel von 32 Bit Zahl (von Joe - 2.04.2015 16:35)