ISAM & PRIMA Teil 3 - die Standardroutinen

Im vorletzten Teil unserer Serie über die Assembler-Macro-Bibliothek „ISAM & PRIMA“ werden die Standardroutinen des Modulpakets vorgestellt - zumeist Arithmetik-Routinen.

Die Artithmetik-Routinen von ISAM & PRIMA arbeiten - besonders bezüglich Kommastellen und Vorzeichen - nach den Regeln der Mathematik. Die Routinen für die Grundrechenoperationen lauten „Plus“, „Minus“, „Durch“ und „Mal“.

Zur Berechnung werden zwei standardisierte Rechenfelder mit den Bezeichnungen REFE1 und REFE2 verwendet. Sie haben folgendes Format:

DC ”0”
REFE1:  DC ”0000000000”
VORZ1:  DC ” + ”
KOMMA1: DC 0 SIGNI1:    DC 0
DC ”0”
REFE2:  DC ”0000000000”
VORZ2:  DC
KOMMA2: DC 0 SIGNI2:    DC 0

Zur Erläuterung: Das Format wird jeweils eine Stelle vor den Feldern REFE1 und REFE2 benötigt. Dies wird von der Routine „NUMERIC“ verlangt, die numerische Werte von der Tastatur holt und in Rechenfelder speichert. Das Feld REFE enthält den numerischen ASCII-Wert mit voranstehenden Nullen, VORZ das jeweilige Vorzeichen (+ oder -), KOMMA die Anzahl der Stellen hinter dem Komma und SIGNI die Position der ersten signifikanten Ziffern relativ zu dem Feld REFE.

Bei Bedarf kann man auch selbst andere Rechenfelder definieren. Das ist etwa beim Zwischenspeichern oder beim Umwandeln von ASCII in Binärformat interessant. Der eigentliche Rechenvorgang findet jedoch stets in den Feldern REFE1 und REFE2 statt.

Die Arithmetik-Routinen werden mit einem JSR 0ump Subroutine) angesprungen. Bei einem Überlauf enthält das Datenregister D0 den Wert -1.

Ein ungenaues Ergebnis entsteht, wenn zuviele signifikante Stellen vorhanden sind. In diesem Fall muß eine bestimmte Anzahl der Stellen nach dem Komma entfernt werden, da sonst ein Überlauf auftritt. Dadurch, daß diese Stellen abgetrennt wurden, erhält man logischerweise ein ungenaues Ergebnis. Das Feld „GENAU“ (.B) enthält dann eine - 1.

Falls keine Überlaufanzeige erfolgte und „GENAU“ eine 0 enthält, ist das Ergebnis absolut genau.

Nun zu den einzelnen Routinen:

INPUT - Eingabe von Zeichen von der Tastatur

Vor dem Aufruf mit JSR INPUT muß in D0 die maximale Anzahl der Zeichen und in A2 die Pufferadresse vorhanden sein. Die tatsächliche Anzahl der Zeichen steht im Anschluß an D0. Die eingegebenen Zeichen findet man im Puffer wieder, wobei sie durch X”00” abgeschlossen werden. Der Puffer muß aus diesem Grund um eine Stelle größer als die längste mögliche Eingabe sein. Wurde ein C eingegeben, gleich an welcher Stelle der Eingabe, so steht beim Rücksprung in D0 eine -3 und an der ersten Pufferstelle X”00”. Man sollte also nach der Rückkehr aus der INPUT-Routine unbedingt D0 auf negativ oder - 3 abfragen.

NUMERIC - Eingabe von numerischen Zeichen von der Tastatur

Bei dieser Routine müssen zuvor einige Felder definiert werden:

TATL:   DC  0
ERG:    BLK 10,"0” ;VOR ANSPRUNG
VORZ:   DC  ”   + ” ;ADR    "ERG" NACH
KOMMA:  DC  0   ;A2 BRINGEN
SIGNI:  DC  0

Vor dem Ansprung mit JSR NUMERIC muß die Adresse ERG in A2 stehen. Die eingegebene Zahl findet man nach der Rückkehr aus dieser Routine in ERG (Länge = zehn Stellen mit führenden Nullen). Die Anzahl der Stellen nach dem Komma steht in KOMMA, die Anzahl der signifikanten Stellen in SIGNI. Es wird eine Prüfung durchgeführt, ob das eingegebene Zeichen numerisch ist. Erfolgt eine falsche Eingabe oder wird nur die RE-TURN-Taste gedrückt oder ist die eingegebene Zahl größer 3.999.999.999, wird D0 vor dem Rücksprung auf - 1 gesetzt. Bei Eingabe von C steht in D0 anschließend eine -3. Alle Register, außer D0, bleiben unverändert.

ABGLEICH - Kommastellen von REFE1 und REFE2 aufeinander abgleichen

Diese Routine wird von den Arithmetik-Routinen verwendet und ist im eigentlichen Sinne keine Standardroutine.

Vor dem Ansprung der Routine muß in D0 (.B) der Minimalwert stehen, den SIGNI annehmen darf. Als Ergebnis erhält man gleiche Nachkommastellen in REFE1 und REFE2. Das Feld mit der geringeren Anzahl von Nachkommastellen wird dabei dem anderen angepaßt. Falls der Minimalwert für SIGNI unterschritten wird, werden rechts Nachkommastellen abgeschnitten. Alle Register bleiben bei dieser Routine unverändert.

Man kann diese Routine ebenfalls zum Erweitern der Nachkommastellen auf eine bestimmte Anzahl nutzen. Dazu nimmt man eines der Rechenfelder als sogenanntes „Dummy“ und gibt im Feld KOMMA die gewünschte Anzahl von Nachkommastellen an, auf die das andere Rechenfeld erweitert werden soll.

UEPLUS - Überlaufkontrolle für Addition und Subtraktion

Diese Routine ist genau wie ABGLEICH keine eigentliche Standardroutine, wird aber von den Arithmetik-Routinen benutzt. Ein Überlauf in den Rechenfeldern wird durch eine -1 im Register D0 angezeigt. Man sollte die Uber-laufkontroll-Routine mit JSR UEPLUS anspringen, nachdem ein Abgleich der Kommastellen stattgefunden hat. UEPLUS versucht dann einen drohenen Überlauf durch Abschneiden von Nachkommastellen abzuwenden.

PLUS - Addition zweier Werte

Durch Aufruf dieser Routine werden die beiden Rechenfelder REFE1 und REFE2 addiert. Das Ergebnis steht anschließend in REFE1.

MINUS - Subtraktion zweier Werte

Diese Routine benutzt die PLUS-Routine, nachdem zuvor eine Vorzeichen-Invertierung stattgefunden hat. Es werden wieder die beiden Rechenfelder benutzt. Das Ergebnis steht anschließend in REFE1.

DURCH - Division zweier Werte

Diese Routine dividiert REFE1 und REFE2. Das Ergebnis steht in REFE1.

MAL - Multiplikation zweier Werte

Durch diese Routine wird REFE1 mit REFE2 multipliziert. Das Ergebnis steht wieder in REFE1.

KNEIF - Abschneiden von Kommastellen ohne Runden

Vor dem Aufruf mit JSR KNEIF muß zuvor die Anzahl der gewünschten Nachkommastellen nach dem Abschneiden an D0 übergeben werden. Ebenso muß der Inhalt des Rechenfeldes REFE1 in A2 stehen. Das Ergebnis findet man danach wieder in REFE1.

ROUND - Runden der Nachkommastellen

Ebenso wie bei KNEIF müssen vor dem Aufruf der Routine die Nachkommastellen an D0 und REFE1 an A2 übergeben werden. Das Ergebnis steht dann wieder in REFE1.

BINASC - Umwandlung von Binär- in ASCII-Format

Vor dem Aufruf der Routine muß die Anfangsadresse von REFE an A2 übergeben werden. Die Binärzahl muß als Langwort in Dl stehen, wobei Bit 31 zur Zahl und kein Vorzeichen möglich ist. Zur Umwandlung wird die Routine DIVI benötigt. Nach dem Aufruf mit JSR BINASC findet man die ASCII-Zahl im Feld REFE 10-stellig mit führenden Nullen wieder. Das Vorzeichen (immer ” + ”) steht in VORZ und die Anzahl der signifikanten Ziffern in SIGNI. Das Feld KOMMA bleibt allerdings unbeeinflußt. Die Register bleiben durch den Aufruf dieser Routine unverändert.

ASCBI - Umwandlung von ASCII- in Binär-Format

Die Adresse von REFE muß vor dem Aufruf der Routine in A2 stehen. Das Vorzeichen bleibt unberücksichtigt. Zur Umwandlung wird die Routine MULTI benötigt. Das Ergebnis steht anschließend in Dl. Alle anderen Register bleiben unverändert.

DIVI - 32 Bit Division

Durch diese Routine wird eine 32 Bit-Division durchgeführt. Vor dem Aufruf muß der Dividend in D1 und der Divisor in D3 stehen. Nach der Ausführung findet man den Quotienten in Dl, den eventuellen Rest in D2 und den Divisor in D3 wieder. Alle anderen Register bleiben unverändert.

MULTI - 32 Bit-Multiplikation

Durch diese Routine wird eine 32 Bit-Multiplikation durchgeführt. Vor dem Aufruf muß der Multiplikant in Dl und der Multiplikator in D2 stehen. Nach der Ausführung findet man das Produkt in Dl wieder. Bis auf Dl und D2 bleiben alle anderen Register unverändert. Eine -1 in D0 zeigt einen eventuellen Überlauf an.

EDIT - Editierroutine

Diese Routine benutzt die Macros TRANSFER und FILL. Es ist also darauf zu achten, daß sie auch im Speicher vorhanden sind. Die Adresse von REFE muß vor dem Ansprung in A2 stehen. Die zu editierende Zahl muß als ASCII-Zahl in den Feldern REFE, KOMMA und SIGNI, wie oben beschrieben, definiert sein. Außerdem ist es notwendig, das Empfangsfeld ED-FLD zuvor festzulegen. Dazu muß in EDFLD die Empfangsfeldlänge und in EDFLD +1 die gewünschte Anzahl der Nachkommastellen stehen. EDFLD ist schon definiert und auf eine maximale Länge von 15 Stellen festgelegt. Die aufbereitete Zahl steht anschließend in der geforderten Länge rechtsbündig mit führenden Leerstellen und Dezimalpunkt in EDFLD. Dabei werden nur negative Vorzeichen eingefügt, positive nicht. Wenn die Länge von EDFLD zu kurz gewählt wurde und deshalb die aufzunehmende Zahl zu groß ist, werden #-Zeichen angezeigt.

Man muß also EDFLD so lang wählen, daß mindestens die Ziffernanzahl, der Dezimalpunkt und das Vorzeichen Platz haben. Erwartet man zum Beispiel Zahlen bis 1000, muß mindestens eine Sechs vor Aufruf der Routine in EDFLD stehen. Alle Register bleiben unverändert.

Wir haben nun den PRIMA-Teil von ISAM & PRIMA abgeschlossen und wenden uns im nächsten Heft dem letzten, dem ISAM-Teil zu. Dies dürfte insbesondere für alle, die sich mit Dateierstellung beschäftigen wollen, sehr interessant werden.

(HE)

INPUT:  MOVEM.L D1-D2/A2,-(SP)
        MOVE.B  D0,D1
        EXT.W   D1              ; MAXIMALE  EINGABE -> Dl
        CLR.L   D2              ;ZÄHLER TATSÄCHL.EING.
IN010:  SUBQ.W  #1,D1
        TST.W   D1
        BMI IN040               ;MAXIMALZAHL ERREICHT
IN020:  INKEY
        TST.L   D0
        BEQ IN020
        CMP.B   #8,D0           ;BACKSPACE?
        BEQ IN030               ;JA
        CMP.B   #13,D0          ;CR ?
        BEQ IN040
        CMP.B   #3,D0           ;^C ?
        BNE IN025               ;NEIN
        MOVE.L  #-3,D0          ;ANZEIGER   F.^C
        MOVEM.L (SP)+,D1-D2/A2
        CLR.B   (A2)                ;X’OO’ AN PUFFERANFANG
        RTS
IN025:  ADDQ.B  #1,D2
        MOVE.B  D0,( A2)+       ;ZEICHEN -> PUFFER
        CHAR        D0
        BRA     IN010
IN030:  TST.B   D2              ;WAREN SCHON ZEICHEN DA ?
        BEQ IN020               ;NEIN, BACKSPACE IGNORIEREN
        SUBQ.B  #1,D2
        ADDQ.W  #1,D1
        SUBQ.L  #1,A2
        MOVE.B  #32,(A2)            ;VORANGEGANGENES ZEICHEN AUF BLANK
        CHAR        #8
        CHAR        #32
        CONTROL.    CLINKS
        BRA     IN020
IN040:  MOVE.L  D2,D0           ;ANZAHL EINGABEZEICHEN
        CLR.B   (A2)                ;X"00" ANS PUFFERENDE
        MOVEM.L (SP)+,D1-D2/A2
        RTS

NUMERIC:    MOVEM.L D1/A0-A2,-(SP)
        MOVE.B  #10,D0          ;MAX.10 ZEICHEN HOLEN
        JSR INPUT               ;PUFFERADR STEHT SCHON IN A2
NUM000: TST.B   D0              ;CONTROL C ?
        BMI NUMEXIT
        MOVE.B  D0,-1(A2)       ;GELESENE ANZAHL -> TATL
        MOVE.B  #"+", 10(A2)        ;MIT PLUS INITIALISIEREN
        TST.B   D0
        BEQ     NUM135          ;NUR ENTER-TASTE
        CMP.B   #"-",(A2)
        BNE     NUM030
NUM010: MOVE.B  (A2),D0         ;VORZEICHEN RETTEN
        MOVE.L  A2.A0
        MOVE.L  A2 , A 1
        ADDQ.L  #1,A1
        MOVE    #9,D1               ;10 STELLEN UM 1 STELLE
NUM020: MOVE.B  (A1)+,(A0)+     ;NACH LINKS
        DBRA    D1,NUM020
        MOVE.B  D0,10(A2)       ;VORZEICHEN
        BRA NUM040
NUM030: CMP.B   #"+",(A2)
        BEQ NUM010
        BRA NUM045
NUM040: SUBQ.B  #1,-1(A2)
NUM045: MOVE.B  -1(A2),D0       ;NACH DEZIMALPKT SUCHEN
        EXT.W   D0              ; IN LANGE TATL
        SUBQ        #1,D0
        MOVE.L  A2,A0           ;AB ERG
NUM050: CMP.B   #".",(AO)+
        DBEQ    D0,NUM050
        TST     D0

BMI NUM080  ;NICHT GEFUNDEN

        SUBQ.L  #1,A0
        MOVE.L  A2,D0   ;ANZAHL NACHKOMMAST. ERRECHNEN
        SUB.L   AO,D0   ;(ADR.ERG + TATL-ADR.PKT - 1)
        SUBQ.L  #1,D0
        MOVE.B  - 1(A2), D1
        EXT.W   D1
        EXT.L   D1
        ADD.L   D1,D0
        MOVE.B  D0,11(A2)
        CMP.B   #0,D0
        BEß NUM070      ;KEINE NACHKOMMASTELLEN
        MOVE.L  A0,A1   ;PUNKT ENTFERNEN
        ADDQ.L  #1,A1   ;AO=EMPF.-FLD, A1=SENDEFELD
        SUBQ.L  # 1 , D0    ;IN LANGE NACHKOMMASTELLEN
NUM060: MOVE.B  (Al)+,(AO)+

DBRA    D0,NUM060

NUM070: SUBQ.B  #1,-1CA2)
        BRA NUM090

NUMCT80:    CLR.B   11CA2)

NUM090: MOVE.B  -1(A2.),D0  ! RECHTSBÜNDIG VERSCHIEBEN
        EXT.W   D0
        SUBQ    # 1 , D0    ; IN LANGE TATL

BMI NUM130  J NUR PUNKT EINGEGEBEN
        MOVE.B  -1(A2),D1   ;AO=SENDEFELD
        EXT.W   D1
        EXT.L   D1
        MOVE.L  D1.A0
        ADD.L   A2,A0
        MOVE.L  A2,A1       ;A1=EMPFANGSFELD
        ADD.L   #10,A1

NUMIOO: MOVE.B  -(A0),-(A1)

DBRA    D0,NUMIOO

MOVE.B  - I(A2),D0  ;FÜHRENDE NULLEN EINFÜGEN

NEG.B   D0  ;LANGE= 10 - TATL

EXT.W   D0

ADD.W   #9,D0

TST.W   D0

BMI NUM115

MOVE.L  A2,AO

NUM110: MOVE.B  #"0",(A0)+

DBRA    D0,NUM110

NUM115: MOVE    #9,D0   ;PRÜFUNG AUF NUMERISCH

MOVE.L  A2,AO

NUM120: CMP.B   #”O"- 1,<A0>

BLS NUM130  ;FEHLER

CMP.B   #-9",CA0)+

DBHI    D0,NUM120

TST D0

EMI NUM140  ;0K,    NUMERISCH

NUM130: MOVE.L  #-l,D0

NUMEXIT:    MOVEM.L (SP)+,D1/A0-A2

RTS

NUM135: MOVE.L  #-2,D0

BRA NUMEXIT

NUM140: CMP.B   #"3",(A2)   ;ZAHL > 3.999.999 999

BHI NUM 1 30    ; JA , ZU GROß

MOVE.W  #9,D0   ;1. SIGNIF.ZIFFER ERMITTELN

MOVE.L  A2,AO

NUM150: CMP.B   #"0“,(A0)+

DBNE    D0,NUM150

SUB.L   A2,AO

SUBQ.L  #I,AO

MOVE.W  AO,D0

MOVE.B  D0,12(A2)

CLR.L   D0

BRA NUMEXIT

ABGLEICH: MOVEM.L   Dl-D3/A1/A2,-(SP)

MOVE.L  #REFE1,A1

MOVE.L  #REFE2,A2

ABGOOO: MOVE.B  11(A1),D1

CMP.B   11 ( A2 ) , D1  > KOMMA 1 > K0MMA2 ?

BGT ABG020  JJA

BLT ABG010  ;KOMMA2 >   KOMMA 1

MOVEM.L (SP)+,D1-D3/A1/A2

RTS

ABG010: EXG A1,A2

^BG020: MOVE.B  12(A2),D1

CMP.B   D0,Dl   ;MINIMALWERT SIGNI ERREICHT

BLE ABG030  ;JA

MOVE.B  12(A2),D1   :REFE2 UM   1 STELLE    NACH LINKS

EXT.W   Dl

EXT.L   D1  1SIGNI2 + ADR REFE2

ADD.L   A2,D1   ;= ADR SENDEFELD -> Dl

MOVE.L  D1,D2   ;ADR SENDEFELD - 1

SUBQ.L  #1,D2   ;= ADR EMPFFLD -> D2

CLR.L   D3  JLANGE

MOVE.B  12(A2),D3   ;=

NEG.L   D3  1 -SIGNI2

ADD.L   #10,D3  1   +10 ->  D3

TRANSFER    D1,D2,D3

MOVE.B  #"0",9<A2)  ;NULL EINFÜGEN

ADDQ.B  #1, 1 1 (A2)    ;KOMMA2 + 1

SUBQ.B  # 1 ,12 C A2)   1SIGNI2 - 1

BRA ABG000

ABG030: MOVE.L  Al,Dl   ;REFE1 UM 1 STELLE NACH RECHTS

MOVE.L  D1,D2

ADDQ.L  #1,D2

TRANSFER    D1,D2,#9

MOVE.B  #"0",< A1>

SUBQ.B  #1,11CA1)

ADDQ.B  #1, 1 2 < A 1 >

MOVE.B  #-l,GENAU

BRA ABGOOO

UEPLUS: MOVEM.L A1/A2,-(SP) ;ÜBERLAUFPRÜFUNG

MOVE.L  #REFE1,A1   ;ADD ITION/SUBTRAKTION

MOVE.L  #REFE2,A2

UEPLUS1:    CMP.B   #2,12<A1>   1SIGNI1 <   2   ?

BLT UEP020  ;JA

UEPOOO: CLR.L   D0

UEP010: MOVEM.L (SP)+,A1/A2

RTS

UEP020: CMP.B   #2,12<A2)   JSIGNI2 <   2   ?

BGE UEPOOO  J NE IN

CMP.B   #0,11(A1>   ;KOMMA 1    >   0   ?

BGT UEP030  1JA

MOVE.L  #-l,D0  ;ÜBERLAUF

BRA UEPOIO

UEP030: MOVE.L  #UEPLUS1,-(SP)  ;RÜCKSPRUNGADRESSE

MOVEM.L D1-D3/A1/A2,-(SP)

JMP ABG030

PLUS:   MOVEM.L Dl-D3/A2,-CSP)

MOVE.B  #2,D0   J MINIMALWERT   SIGNI

CLR.B   GENAU

JSR ABGLEICH

JSR UEPLUS

TST.L   D0

BEQ PLU020  ;KEIN ÜBERLAUF

PLU010: MOVEM.L (SP)+,D1-D3/A2

RTS

PLU020: MOVE.L  #REFE2,A2

JSR ASCBI

MOVE.L  D1,D2

MOVE.L  #REFE1,A2

JSR ASCBI

CMP.B   #"+".REFE1+10

BEQ PLU030

CMP.B   .REFE2+10

BEQ PLU070

BRA PLU040

PLU030: CMP.B   #"+",REFE2+10

BEQ PLU060

PLU040: CMP.L   D2.D1

BHI PLU050

EXG D1,D2

MOVE.B  REFE2+10,D3

BRA PLU055

PLU050: MOVE.B  REFE1+10.D3

PLU055: SUB.L   D2,D1

BRA PLU999

PLU060: MOVE.B  #"+",D3

PLU065: ADD.L   D2,D1

BRA PLU999

PLU070: MOVE.B  #"-",D3

BRA PLU065

PLU999: JSR BINASC

MOVE.B  D3,REFE1+10

JSR NULWEG

BRA PLU010

MINUS:  EOR.B   #6,REFE2+10 JVORZEICHEN INVERTIEREN

JSR PLUS

EOR.B   #6,REFE2 +10

RTS

DURCH:  MOVEM.L D 1-D5/AO,-CSP)

MOVE.L  #1,00   ;MINI MALWERT SIGNI = 1

CLR.B   GENAU

JSR ABGLEICH

MOVE.B  REFE1+10,D0 ;VORZEICHEN REFE1

CMP.B   REFE 2 + l0,D0  ;= VORZEICHEN REFE2 ?

BNE DU002   ;NEIN, ERGEBNIS NEGATIV

MOVE.B  #"+",-(SP)  ;JA, ERGEBNIS POSITIV

BRA DU004

DU002:  MOVE.B  #"-',-(SP)

DU004:  MOVE.L  #REFE2,A2

JSR ASCBI

MOVE.L  D1,D3   ;REFE2 -> D3

MOVE.L  #REFE1,A2   :REFE1 = DIVIDEND

JSR ASCBI   ;   -> Dl

TST.L   D3  ;DIVISOR    = 0

BNE DU006

DU005:  MOVE.B  (SP)+,D0    ;ÜBERLAUF   ODER /O,    STACKKORREKTUR

MOVE.L  #-l,D0  ;FEHLERANZEI GER

BRA DU999

DU006:  JSR DIVI

DU007:  JSR BINASC  ;VORKOMMAST.    -> REFE1

MOVE.L  #REFE1,D4   ;ADREMPF -> D4

CLR.L   Dl  JSIGNI + ADRREFE1

MOVE.B  REFE1+12,D1 ;=

ADD.L   D4,D1   ;ADRSEND    -> Dl

MOVE.B  REFE1+12,D0

NEG.B   D0  SIGNI

EXT.W   D0  ;+  10

ADD.W   #10,D0  ;=  LÄNGE   -> D0

TRANSFER    D1,D4,D0

MOVE.B  REFE1 + 12, D1

NEG.B   Dl  SIGNI

EXT.W   Dl  ;+  ADRREFE1

EXT.L   D1  ;+  10

ADD.L   #REFE1+10,D1    J = ADREMPF -> Dl

MOVE.B  REFE1+12,D0 ;LANGE = SIGNI -> D0

EXT.W   D0

FILL    Dl,D0,#"0"  JRECHTS NULLEN EINFÜGEN

MOVE.B  REFE1+12,D5

SUBQ.B  #1,D5

BMI DU020

EXT.W   D5

EXT.L   D5

MOVE.L  #0,AO

SUB.L   D5,A0

ADD.L   #REFE1+9,A0

DU010:  TST.L   D2  ;REST   =   0   ?

BEQ DU020   : JA

MOVE.L  #10,Dl

JSR MULTI   ;REST   *   10

TST D0  ;ÜBERLAUF   ?

BMI DU005   ;JA

DUO 15: JSR DIVI    ;/ DIVISOR

OR.B    #$30,Dl ;= NÄCHSTE  NACHKOMMASTELLE

MOVE.B  D1,(A0)+

DBRA    D5.DU010

DU020:  MOVE.B  REFE1+12,REFE1+11   ;KOMMA = SIGNI

CLR.B   REFE1+12    JSIGNI = O

DUEXIT: MOVE.B  (SP)+,REFE1+10  JVORZEICHEN EINSTEUERN

JSR NULWEG

CLR.L   D0

DU999:  MOVEM.L (SP)+,D1-D5/AO

RTS

MAL:    MOVEM.L D 1/D2/A1/A2,-<SP>

CLR.B   D0

CLR.B   GENAU

MOVE.B  REFE1+10,D0

CMP.B   REFE2+10,D0

BNE MA020

MOVE.B  #"+",-(SP>

BRA MA025

MA020:  MOVE.B  #"-",-<SP)

MA025:  MOVE.L  #REFE2,A2

JSR ASCBI

MOVE.L  D1,D2

MOVE.L  #REFE1 , A2

JSR ASCBI

JSR MULTI

TST.B   D0

BPL MA030

BRA MA040

MAEXIT: MOVE.B  (SP)+,REFE1+10

JSR NULWEG

MA999 : MOVEM.L <SP>+,D1/D2/A1/A2

RTS

MA030:  MOVE.B  REFEl+ll.D0

ADD.B   REFE2+11,D0

CMP.B   #10,D0

BGT MA045

MOVE.B  D0,REFE1+11

JSR BINASC

TST.B   D0

BEQ MAEXIT

NEG.B   D0

ADD.B   #10,D0

BNE MA032

CLR.B   REFE1+12

BRA MAEXIT

MA032:  CMP.B   REFE1+12.D0

BLT MA034

BRA MAEXIT

MA034:  SUBS.B  #1,D0

MOVE.B  D0,REFE1+12

BRA MAEXIT

MA040:  MOVE.B  REFEl + ll.D0

CMP.B   REFE2+11,D0

BGT MA042

TST.B   REFE2+1 1

BEQ MAO 45

MOVE.L  #REFS2,A1

MA04S:  JSR MAC60

MOVE.B  #-i,GENAU

BRA MA025

MA042:  MOVE.L  #REFE1,A1

BRA MA041

MA045:  MOVE.L  #-l,D0

ADDQ.L  #2,SP

BRA MA999

MAOGO:  MOVE.L  Al,Dl

MOVE.L  D1.D2

ADDQ.L  #1,D2

TRANSFER    D1,D2,#9

MOVE.B  #"0“,(A1)

SUBQ.B  # 1 , 1 1 (A 1)

ADDQ.B  #1, 1 2 C A1)

RTS

NULWEG: MOVEM.L D1/D2/A1,-<SP) »RECHTSBÜNDIGE NULLEN ENTFERN

MOVE.L  fiREFEl,Al

NULOOO: CMP.B   #"0".REFE1+9

BNE NUL005

TST.B   REFE1+11

BNE NUL010

NUL005 :    MOVEM.L (SP) + ,D1/D2/A1

RTS

NUL010: MOVE.B  REFE1+12,D1

CMP.B   #9,Dl

BGE NUL005

JSR MAOGO

BRA NULOOO

ROUND:  MOVEM.L D1-D3/A3,-(SP)

MOVE.B  11(A2),D1   ;TATSACHL.KOMMAST. -> Dl

SUB.B   D0,Dl   GEWÜNSCHTE  KOMMAST.

CMP.B   #1,D1

BLT R0020   :HAT SICH ERLEDIGT

MOVE.B  D0.1KA2)    ; NEUE = GEWÜNSCHTE KOMMAST.

EXT.W   Dl  ;= VERSCHIEBELÄNGE  ->  Dl

EXT.L   D1

MOVE.L  D1.D2   JIO -   VERSCHIEBELANGE

NEG.L   D2  ;=

ADD.L   #10,D2  ;TRANSFERLÄNGE -> D2

MOVE.L  D2,A3

CMP.B   #$34,0(A3,A2)   ;ABKNEIFSTELLE > 4 ?

BLE ROOIO   ,-NEIN

MOVE.B  #-1,D0  5MERKMAL RUNDEN

ROOIO:  MOVE.L  D1.D3   ;VERSCHIEBELÄNGE RETTEN

ADD.L   A2,D1   ;REFE+VERSCHIEBELÄNGE=EMPF.-ADR.

TRANSFER    A2,D1,D2

FILL    A 2,D 3,#"0"

CMP.B   #-1,D0  :RUNDEN ?

BNE R0012   ;NEIN

JSR ASCBI   ;ZAHL   ->  Dl

ADDQ.L  #1,D1   ;+1

JSR BINASC  ;ZAHL   ZURÜCK

R0012:  MOVE.W  #9,D0   ; 1 . SIGNIF.ZI FF.ERMITTELN

MOVE.L  A2,A0

R0015:  CMP.B   #“0",(A0)+

DBNE    D0,ROO15

SUB.L   A 2,AO

SUBQ.L  #1,AO

MOVE.W  AO,D0

MOVE.B  D0,1 2(A2)

R0020:  MOVEM.L (SP)+,D1-D3/A3

RTS

KNEIF:  MOVEM.L D1-D3/A3,-(SP)

MOVE.B  I1<A2),D1   ;TATSACHL.KOMMAST. -> Dl

SUB.B   D0,DI   GEWÜNSCHTE  KOMMAST.

CMP.B   #1,D1

BLT KN020   ;HAT SICH ERLEDIGT

MOVE.B  D0,11(A2)   » NEUE = GEWÜNSCHTE KOMMAST.

EXT.W   Dl  ;= VERSCHIEBELÄNGE -> Dl

EXT.L   D1

MOVE.L  D1,D2   510 - VERSCHIEBELÄNGE

NEG.L   D2  ;=

ADD.L   #10,D2  ;TRANSFERLÄNGE -> D2

MOVE.L  D2,A3

KN010:  MOVE.L  D1.D3   ;VERSCHIEBELÄNGE RETTEN

ADD.L   A2.D1   ;REFE+VERSCHIEBELÄNGE=EMPF.-ADR.

TRANSFER    A2,D1,D2

FILL    A2,D3,#"0"

KN012:  MOVE.W  #9,D0   ;1.SIGNIF.ZI FF.ERMITTELN

MOVE.L  A2,AO

KN015:  CMP.B   #"0",(A0>+

DBNE    D0,KNO15

SUB.L   A2,AO

SUBQ.L  #1,AO

MOVE.W  AO,D0

MOVE.B  D0,12 C A 2 >

KN020:  MOVEM.L (SP)+,D1-D3/A3

RTS
BINASC: MOVEM.L D0-D3/AO/A2,-(SP)

MOVE.L  #10,D3  1DIVIS0R

MOVE.L  A2,A0

MOVE    #10,D0  »11 STELLEN ERGEBNIS

BINAOOO:    MOVE. B #“0",(A0>+  »‘NULLEN EINFÜGEN

DBRA    D0,BINAOOO

MOVE.B  #-+-,-<A0>

BINA020:    JSR DIVI

OR.B    #$30,D2 »REST

MOVE.B  D2,-(AO)

CMP.L   #0,D1   ;QUOTIENT = 0   ?

BEQ BINA030 1JA, FERTIG

JMP BINA02O

BINA030:    MOVE.W  #9,D0   11.SIGNIF.ZIFF.ERMITTELN

MOVE.L  A2,AO

BINA040:    CMP.B   #"0",(A0)+

DBNE    D0,BINA040

SUB.L   A2,AO

SUBQ.L  #1,AO

MOVE.W  AO,D0

MOVE.B  D0,12(A2)

MOVEM.L (SP)+,D0-D3/AO/A2

RTS 1 ASCII STEHT BEREIT

ASCBI:  MOVEM.L D0/D2/D3/A0-A2,-(SP)

MOVE.W #9,D3    ;10 STELLEN

MOVE.L  A2,AO

CLR.L   Dl

MOVE.L  #10,D2

AS010:  MOVE.L  D0,-(SP)

JSR MULTI

MOVE.L  (SP)+,D0

MOVE.L  D1,A1

CLR.L   Dl

ADD.B   (AO)+,D1

SUB.B   #$30,Dl

ADD.L   Al,Dl

DBRA    D 3,AS 010

MOVEM.L (SP)+,D0/D2/D3/A0-A2

RTS

DIVI:   MOVEM.L D0/D3/D4,-(SP)

MOVE.L  D3,D4

MOVE    #31,D0

CLR.L   D2

CLR.L   D3

DIVI020:    ROXL.L  #1,D1   iDIVIDEND   IN Dl

ROXL.L  #1,D2   :1 BIT VON Dl NACH D2 ZIEHEN

ASL.L   #1,D3   1 QUOTIENT  1 BIT SCHIEBEN

SUB.L   D4,D2   1DIVIS0R IN D4

BMI DI VI040

ADDQ.L  #1,D3   ;QUOTIENT   IN D3

DI VI030:   DBRA    D0,DIVI0'2O

MOVE.L  D3,D1

MOVEM.L (SP)+,D0/D3/D4

RTS

DIVI040:    ADD.L   D4,D2   ;WIEDERHERSTELLEN

BRA DIVI030

MULTI:  MOVEM.L D2-D4,-(SP)

CLR.L   D3

CLR.B   D4

MOVE.W  #31,D0

MUL010: ROR.L   #1,D2

BCC MUL020

TST.B   D4

BMI MUL015

ADD.L   D1,D3

BCC MUL020

MUL015: MOVE.L  #-l,D0

BRA MULEXIT

MUL020: ASL.L   #1,D1

BCC MUL030

MOVE.B  #-l,D4

MUL030: DBRA    D0.MÖLOIO

MOVE.L  D3,D1

CLR.L   D0

MULEXIT:    MOVEM.L (SP)+,D2-D4

RTS

EDIT:   MOVEM.L D0-D7/AO-A2,-(SP)

MOVE.B  EDFLD,D5    !LÄNGE EMPFANGSFELD RETTEN

MOVE.B  EDFLD+1,D6  iGEWÜNSCHTE NACHKOMMASTELLEN

MOVE.B  #10,D0  ;LÄNGE VORKOMMASTELLEN

SUB.B   11(A2),D0

SUB.B   12(A2),D0

CMP.B   #0,D0

BGT ED005

CLR.B   D0

ED005:  EXT.W   D0  ;NACH D0

EXT.L   D0

MOVE.B  D6,DI   ; WENN GEWÜNSCHT. NACHKOMMAST.

ADDQ.B  #2,Dl   ;+  LÄNGEN DEZIMALPUNKT U. VORZEICH.

ADD.B   D0,Dl   ;+  LÄNGE VORKOMMASTELLEN

CMP.B   D5,D1   ; > FELDLANGE EDFLD, DANN

BHI ED030   ;   EDFLD ZU KURZ

MOVE.B  D5,D1   5GEWÜNSCHTE EMPFANGSLÄNGE

SUB.B   D6.D1   GEWÜNSCHTE NACHKOMMASTELLEN

SUBQ.B  #1,Dl   1

EXT.W   Dl

EXT.L   D1

ADD.L   #EDFLD,D1   ;+  ADR. EDFLD

MOVE.L  D1,A1

MOVE.B  A1) ;= ADR. DEZIMALPUNKT

MOVE.L  D1,D3   ;RETTEN

SUB.L   D0,Dl   LANGE VORKOMMASTELLEN

MOVE.L  D1,D4   ;RETTEN

MOVE.B  12 < A2),D2 1DISPLACEMENT 1.SIGNIF.STELLE

EXT.W   D2

EXT.L   D2

ADD.L   A2,D2   ;+ ADR. ERG

TRANSFER    D2.D1.D0

MOVE.B  #10,D1  110

SUB.B   11(A2),D1   5- NACHKOMMASTELLEN

EXT.W   Dl

EXT.L   D1

ADD.L   A2,D1   ;+ ADR ERG

MOVE.L  D3,D2   ;ADR DEZIMALPUNKT

ADDQ.L  #1,D2   ;+l = EMPFANGSADR.NACHKOMMA -> D2

CMP.B   11(A2),D6   ITATSACHL.VORH./GEWÜNSCHT.NACHKOMMAST

BGT ED020   ;MEHR GEWÜNSCHT ALS.VORHANDEN

MOVE.B  D6,D0

ED010:  EXT.W   D0

TRANSFER    D1,D2,D0

MOVE.L  D4,D0   ;EMPF.ADR. VORKOMMASTELLEN

SUB.L   #EDFLD,D0   ADR EDFLD

FILL    #EDFLD,D0,#" * ;FÜHRENDE BLANKS EINFÜLLEN

CMP.B   #*-",10(A2) JNEGATIVES VORZEICHEN ?

BNE ED999   ;NEIN

MOVE.L  D4,A0   ;EMPF.ADR.VORKOMMASTELLEN

SUBQ.L  #1,AO   1

MOVE.B  #"-■*, CAO) ;= VORZEICHENSTELLE

ED999:  MOVEM.L (SP) +, D.0-D7 / A0-A2

RTS

ED020:  MOVE.B  D6,D0   ; GEWÜNSCHTE NACHKOMMASTELLEN

SUB.B   11(A2),D0   ; VORHANDENE

EXT.W   D0 ; MIT NULLEN AUFZUF.STELLEN

MOVE.B  11<A2>,D7   ;VORHANDENE NACHKOMMASTELLEN

EXT.W   D7

EXT.L   D7

ADD.L   D2,D7   ;+ EMPF.ADR.NACHKOMMASTELLEN

FILL    D7,D0,#"0"  ;NACHKOMMASTELLEN AUFFÜLLEN

MOVE.B  11<A2),D0   ;IN TATSÄCHL.VORH.LÄNGE

BRA ED010   ;üBERTRAGEN

ED030:  FILL    #EDFLD,D5,#"#" ; AUFFÜLLEN MIT #, DA ZU KURZ

BRA ED999

ENDSTAND: EQU   *


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]