![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
Hallo, an alle ASM-Programmierer. Anbei ASM-Routinen. Laufen bei mir unter "Calc32bit.PRO". Habe die Routinen zum Schreiben eines Programms zum Lesen/Beschreiben von SD-Karten mt der MAXI benutzt. Frohe Weihnachten und ein erfolgreiches 2014. GeKue ' GeKue, Halle/Saale ' > 32 B i t R e c h e n o p e r a t i o n e n '------------------------------------------------------------------------------------- ' Genutzt werden die durch Dietmar Harlos am 7. Juni 2006 ' veröffentlichten Routinen mit leichten Änderungen '------------------------------------------------------------------------------------- ' Inhalt: ' Addition: ASMB1=ASMB1+ASMB2 ;ASMB2 bleibt unverändert ' Subtrahiere: ASMB1=ASMB1-ASMB2 (mit ASMB1>ASMB2) ;ASMB2 bleibt unverändert ' Multipliz32Bit: ASMB1=ASMB1*ASMB2 (nutzt ASMB3) ;ASMB2 & ASMB3 auf 0 ' Multipliz16Bit: ASMB1=ASMB1*ASMB2 (nutzt ASMB3) ;ASMB2 & ASMB3 auf 0 ' Dividiere: ASMB1=ASMB1:ASMB2 (mit ASMB1>ASMB2) ;ASMB2 bleibt unverändert; Rest in ASMB3 ' Unterschied: Vergleicht ASMB1 mit ASMB2 => Ergebnis im Status-Register (C,Z wenn ASMB1<; nur Z wenn ' ASMB1=ASMB2), läßt ASMB1 -ASMB4 unverändert ' Clean_ASMZ: Setzt ASMB1-ASMB3 auf 0 ' ASMB1_to_ASMB4: Rettet ASMB1 in ASMB4 ' ASMB4_to_ASMB2: Schiebt ASMB4 nach ASMB2 ' ASMB1_to_ASMB3: Schiebt ASMB1 nach ASMB3 ' ASMB3_to_ASMB1: Schiebt ASMB3 nach ASMB1 ' SWAP_ASMB_1_2: Vertauscht ASMB1 mit ASMB2 ' DezimalAusgabe: Gibt ASM1a-d dezimal aus ;Ändert ASMB1 - ASMB3 und A,H,X ' CLS_ASMB1: Setzt ASMB1d-d auf 0 ' CLS_ASMB2: Setzt ASMB2d-d auf 0 ' Programm nutzt die mit "Define" definierten Speicher. ' Da Schiebeoperationen benutzt werden, müssen die Speicherbereiche innerhalb einer 32Bit-Zahl zusammenhängend sein ' werden sie einzeln konkret definiert, muß ASMBxd eine kleinere Ordnungszahl als ASMBxa besitzen, wie z.B.: ' DEFINE ASMB1d BYTE[ 41] ' DEFINE ASMB1c BYTE[ 42] ' DEFINE ASMB1b BYTE[ 43] ' DEFINE ASMB1a BYTE[ 44] ' Nutzt man die MAXI, müssen die Variablen im unteren Speicherbereich definiert werden ' zum Sparen von Programmierplatz, die nicht genutzten Routinen auskommentieren.... '************************************************************************************* ' DezimalAusgabe von 32-Bit-Zahlen (<99.999.999) '*********************************************************************************** Table DezAusgab Byte '10.000.000 1.000.000 100.000 10.000 1.000 100 10 1 &H98,&H96,&H80,&HF,&H42,&H40,&H1,&H86,&HA0,&H0,&H27,&H10,&H0,&H3,&HE8,&H0,&H0,&H64,&H0,&H0,&HA,&H0,&H0,&H1 Tabend ' 1.000.000.000 100.000.000 10.000.000 ' 3B9ACA00 5F5E100 989680 Proc DezimalAusgabe Inlasm #DezimalAusgabe_wI ' -(without Inlasm) Direktaufruf aus anderem Assemblerprogramm ! LDA ASMB4a:!PSHA 'ASMB4a retten ! LDHX #DezAusgab ! PSHH ! PSHX ! CLR ASMB4a #Dez_Loop ! CLR ASMB2d ! ClR ASMB2d ! PULX ! PULH ! MOV ,X+,ASMB2c ' Divisor ! MOV ,X+,ASMB2b ! MOV ,X+,ASMB2a ! PSHH ! PSHX ! CLRA ' Zero für GibZero ! JSR Unterschied ! BLO GibZero ' Wenn ASMB1 ! JSR Dividiere ! LDA ASMB1a ' Ergebnis ! JSR ASMB3_to_ASMB1 ' Rest nach ASMB1 #GibZero ! BRCLR #0,ASMB4a,NextDivisor2 'wenn noch keine Ziffer>0 war ! Add #"0" ! JSR FWPutSCI #NextDivisor2 ! lda ASMB2a ! CBEQA #1,DezEnd 'letzter Divisor ! BRA Dez_Loop #DezEnd ! PULX ! PULH ! PULA:!STA ASMB4a 'ASMB4a wieder restaurieren ! RTS '***************************************************************************************** ' SWAP ASMB_1_2: Vertauscht ASMB1 mit ASMB2 (A:H:X )=3 -ok '***************************************************************************************** #SWAP_ASMB_1_2 ' ! PSHH ' sichere ! PSHX ' A:H:X ! PSHA ' ! LDHX #ASMB1d 'LSB #SWAP_L1 ! LDA ,X '1a ! PSHA '1a => 1,SP ! LDA $4,X '2a ! STA ,X '2a => 1a ! PULA '1a ! STA $4,X '1a => 2a ! INCX ' c,b,a... ! CPX #ASMB1a +1 ! BNE SWAP_L1 ' ! PULA ' restauriere ! PULX ' A:H:X ! PULH ! RTS '*************************************************************************************** '* Clean_ASMB: Löscht ASMB1,ASMB2,ASMB3 * ************************************************************************************** #Clean_ASMB ! LDHX #0 ! STHX ASMB1d ! STHX ASMB1b ! STHX ASMB2d ! STHX ASMB2b ! STHX ASMB3d ! STHX ASMB3b ! RTS '**************************************************************************************** ' CLS_ASMB2 Löscht ASMB2 439 -ok '**************************************************************************************** #CLS_ASMB2 ! PSHH:!PSHX ! LDHX #0 ! STHX ASMB2d ! STHX ASMB2b !PULX:!PULH ! RTS '**************************************************************************************** ' CLS_ASMB1 Löscht ASMB1 439 -ok '**************************************************************************************** #CLS_ASMB1 !PSHH:!PSHX ! LDHX #0 ! STHX ASMB1d ! STHX ASMB1b !PULX:!PULH ! RTS '**************************************************************************************** ' ASMB1_to_ASMB3 Schiebt ASMB1 nach ASMB3 -ok '**************************************************************************************** #ASMB1_to_ASMB3 ! MOV ASMB1d,ASMB3d ! MOV ASMB1c,ASMB3c ! MOV ASMB1b,ASMB3b ! MOV ASMB1a,ASMB3a ! RTS '**************************************************************************************** ' ASMB3_to_ASMB1 Schiebt ASMB3 nach ASMB1 -ok '**************************************************************************************** #ASMB3_to_ASMB1 ! MOV ASMB3d,ASMB1d ! MOV ASMB3c,ASMB1c ! MOV ASMB3b,ASMB1b ! MOV ASMB3a,ASMB1a ! RTS '**************************************************************************************** ' ASMB1_to_ASMB4 Schiebt ASMB1 nach ASMB4 -ok '**************************************************************************************** #ASMB1_to_ASMB4 ' Rettet ASMB1 in ASMB4 ! MOV ASMB1d,ASMB4d ! MOV ASMB1c,ASMB4c ! MOV ASMB1b,ASMB4b ! MOV ASMB1a,ASMB4a ! RTS '**************************************************************************************** ' ASMB4_to_ASMB2 Schiebt ASMB4 nach ASMB2 -ok '**************************************************************************************** #ASMB4_to_ASMB2 ' Schiebt ASMB4 nach ASMB2 ! MOV ASMB4d,ASMB2d '12 ! MOV ASMB4c,ASMB2c ! MOV ASMB4b,ASMB2b ! MOV ASMB4a,ASMB2a ! RTS '********************************************************************************** ' Unterschied: ? ASMB1 >,=,< ASMB2 => Result im CCR ok ' SP=2 ; '********************************************************************************** #Unterschied ! PSHH ! PSHX ! LDHX ASMB1d ! CPHX ASMB2d ! BEQ Untersch1 ! BRA Untersch_End #Untersch1 ! LDHX ASMB1b ! CPHX ASMB2b #Untersch_End ! PULX ! PULH ! RTS '***************************************************************************** ' Addition: ASMB1abcd=ASMB1 + ASMB2 ok '**************************************************************************** #Addition 'Addiert 32BIT mit 32Bit nach ASMB1d-c ! LDA ASMB1a 'Routine hat 24 Byte ! ADD ASMB2a ' und nur 36 Cyclen ! STA ASMB1a ! LDA ASMB1b ! ADC ASMB2b ! STA ASMB1b ! LDA ASMB1c ! ADC ASMB2c ! STA ASMB1c ! LDA ASMB1d ! ADC ASMB2d ! STA ASMB1d ! RTS '************************************************************** '* Multiplizieren \ '* ASMB1=> Result | 1 SP '* 2=> gelöscht | '* 3=> gelöscht / '************************************************************** #Multipliz32Bit '1628 Cyclen ! LDA #32 ! BRA MultiplizierStart #Multipliz16Bit ' 957 Cyclen ! LDA #16 #MultiplizierStart ! JSR ASMB1_to_ASMB3 'B3=B1 ! JSR CLS_ASMB1 'B1=0 #ShiftRight3 ' ! PSHA #ShiftRight3a ! LSR ASMB3d ' B3=ROR Z3 ! ROR ASMB3c ! ROR ASMB3b ! ROR ASMB3a ! BCC Shiftleft2 ! JSR Addition 'if C then B1=B2+B1' #Shiftleft2 ' ! LSL ASMB2a ' B2=ROL B2 ! ROL ASMB2b ! ROL ASMB2c ! ROL ASMB2d ! PULA ! DBNZA ShiftRight3 ! RTS '************************************************************************************* ' Subtrahieren: ASMB1=ASMB1 - ASMB2 ASMB1>ASMB2 '************************************************************************************* #Subtrahiere ' Berechnet Differenzen' 24 Zahl1>Zahl2 ! PSHA ! PSHX ! PSHH ' ! LDA ASMB1a ! SUB ASMB2a ! STA ASMB1a ! LDA ASMB1b ! SBC ASMB2b ! STA ASMB1b ! LDA ASMB1c ! SBC ASMB2c ! STA ASMB1c ! LDA ASMB1d ! SBC ASMB2d ! STA ASMB1d ! PULH ! PULX ! PULA ! RTS '********************************************************************************************* '* 32-Bit-Division '* '********************************************************************************************* #Dividiere ' ! PSHX ! PSHH ! LDA ASMB1d ! ORA ASMB1c ! ORA ASMB1b ! ORA ASMB1a ! CBEQA #0,EndDiv #udiv32 ! clr ASMB3d ' Rest loeschen 1666 ! clr ASMB3d+1 ' ! clr ASMB3d+2 ' ! clr ASMB3d+3 ! mov #32,OsTemp ' Zähler einstellen #udiv32_1 ! lsl ASMB1d+3 'Divident (und Quotient, Ergebnis) a nach links ... ! rol ASMB1d+2 ! rol ASMB1d+1 ! rol ASMB1d ! rol ASMB3d+3 ' in den ZwischenSpeicher schieben ! rol ASMB3d+2 ! rol ASMB3d+1 ! rol ASMB3d ! lda ASMB3d+3 'ZwischenSpeicher minus Divisor ! sub ASMB2d+3 ! lda ASMB3d+2 ! sbc ASMB2d+2 'Zwischenspeichern der ersten Ergebnisse per PUSHA ! lda ASMB3d+1 ' macht keinen Sinn, da der Akku in den meisten ! sbc ASMB2d+1 ' Faellen nicht aktualisiert werden muss. ! tax ' a nach x ! lda ASMB3d ! sbc ASMB2d ! bcs udiv16_2 'Carry ist gesetzt, wenn Akku kleiner als Divisor ! sta ASMB3d ! stx ASMB3d+1 'wenn nicht zu klein, dann Akkumulator aktualisieren ! lda ASMB3d+3 ! sub ASMB2d+3 ! sta ASMB3d+3 ! lda ASMB3d+2 ! sbc ASMB2d+2 ! sta ASMB3d+2 ! inc ASMB1d+3 ' und LSB vom Quotienten setzen, wird oben bei udiv32_1 #udiv16_2 ' nach links 32 mal durchgereicht ! dbnz OsTemp,udiv32_1 #EndDiv ! PULH ! PULX ! RTS '*********************************************************************** |
Antwort schreiben |