
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
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 > ' > ' fr 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] = > ' var[12:02] = > 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] = > ' 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 |