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 D1, 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	#".",(A0)+
		DBEQ	D0,NUM050
		TST		D0

BMI	NUM080	;NICHT GEFUNDEN

		SUBQ.L	#1,A0
		MOVE.L	A2,D0	;ANZAHL NACHKOMMAST. ERRECHNEN
		SUB.L	A0,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	(A1)+,(A0)+

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	;A0=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

NUM100:	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,A0

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

DBRA	D0,NUM110

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

MOVE.L	A2,A0

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

BLS	NUM130	;FEHLER

CMP.B	#-9",CA0)+

DBHI	D0,NUM120

TST	D0

EMI	NUM140	;OK,	NUMERISCH

NUM130:	MOVE.L	#-1,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,A0

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

DBNE	D0,NUM150

SUB.L	A2,A0

SUBQ.L	#1,A0

MOVE.W	A0,D0

MOVE.B	D0,12(A2)

CLR.L	D0

BRA	NUMEXIT

ABGLEICH: MOVEM.L	D1-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,D1	;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,11(A2)	;KOMMA2 + 1

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

BRA	ABG000

ABG030:	MOVE.L	Al,D1	;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,12 < A 1 >

MOVE.B	#-1,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	#-1,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	#-1,D0	;FEHLERANZEIGER

BRA	DU999

DU006:	JSR	DIVI

DU007:	JSR	BINASC	;VORKOMMAST.	-> REFE1

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

CLR.L	D1	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	D1	SIGNI

EXT.W	D1	;+	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	D1,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,A0

SUB.L	D5,A0

ADD.L	#REFE1+9,A0

DU010:	TST.L	D2	;REST	=	0	?

BEQ	DU020	: JA

MOVE.L	#10,D1

JSR	MULTI	;REST	*	10

TST	D0	;ÜBERLAUF	?

BMI	DU005	;JA

DUO 15:	JSR	DIVI	;/ DIVISOR

OR.B	#$30,D1	;= 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	#-1,D0

ADDQ.L	#2,SP

BRA	MA999

MAOGO:	MOVE.L	Al,D1

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,D1

BGE	NUL005

JSR	MAOGO

BRA	NULOOO

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

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

SUB.B	D0,D1	GEWÜNSCHTE	KOMMAST.

CMP.B	#1,D1

BLT	R0020	:HAT SICH ERLEDIGT

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

EXT.W	D1	;= 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,A0

SUBQ.L	#1,A0

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	D1	;= 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,A0

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

DBNE	D0,KNO15

SUB.L	A2,A0

SUBQ.L	#1,A0

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,-(A0)

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

BEQ	BINA030	1JA, FERTIG

JMP	BINA02O

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

MOVE.L	A2,A0

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

DBNE	D0,BINA040

SUB.L	A2,A0

SUBQ.L	#1,A0

MOVE.W	A0,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,A0

CLR.L	D1

MOVE.L	#10,D2

AS010:	MOVE.L	D0,-(SP)

JSR	MULTI

MOVE.L	(SP)+,D0

MOVE.L	D1,A1

CLR.L	D1

ADD.B	(A0)+,D1

SUB.B	#$30,D1

ADD.L	A1,D1

DBRA	D3,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	#-1,D0

BRA	MULEXIT

MUL020:	ASL.L	#1,D1

BCC	MUL030

MOVE.B	#-1,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,D1	;+	LÄNGEN DEZIMALPUNKT U. VORZEICH.

ADD.B	D0,D1	;+	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,D1	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,D1	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,A0	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	*


Aus: ST-Computer 01 / 1987, Seite 92

Links

Copyright-Bestimmungen: siehe Über diese Seite