Der Nachfolger des WDR-Computerclub mit Wolfgang Back und Wolfgang Rudolph - ...und immer ein Bit übrigbehalten!


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 

 ASM-Hilfen Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von GeKue - 22.12.2013 10:36)
GeKue nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro
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 !        MOV #129,ASMB4a     ' vermeide führende Nullen
!        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

Bisherige Antworten: