ISAM & PRIMA: Zwei Assembler-Macro-Modulbibliotheken

Die ISAM- und PRIMA-Macrobefehle sind in der hier veröffentlichten Form für den SEKA-Assembler der englischen Firma KUMA gedacht. Falls man einen anderen Macro-Assembler benutzen möchte, muß man die Macromodule gegebenenfalls an dessen Macrosyntax anpassen. Die Standardroutinen können unverändert übernommen werden, sofern der andere Assembler die Standard-Motorola Mnemoniks beherrscht.

Beide Bibliotheken sind von Gerhard Pritz aus Berlin erstellt und von uns für die ST Computer erworben worden. Die Source-Listings werden von der nächsten Ausgabe ab regelmäßig veröffentlicht. In dieser Ausgabe soll das Modulpaket zunächst erst einmal vorgestellt und eine kurze Einleitung gegeben werden. Eine komplette Veröffentlichung in einer Ausgabe würde den Rahmen der ST Computer sprengen und außerdem die vielen Assembleruninteressierten stark benachteiligen. Die Listings sind natürlich auf den jeweiligen, zur Ausgabe gehörigen, Disketten vorhanden. Ferner kann man das komplette Paket, also ISAM und PRIMA, für ganz Eilige schon jetzt auf einer Extra-Diskette für DM 49,- + DM 5,- Versandkosten, gegen Vorausscheck oder per Nachnahme, beim Heim-Verlag in Darmstadt, beziehen (beiliegende Software-Bestellkarte verwenden).

Um nun erst einmal zu erklären, was ISAM und PRIMA überhaupt sind bzw. beinhalten, wollen wir darauf kurz eingehen.

ISAM ist die Abkürzung für Indexed Sequential Access Method. Es handelt sich also um eine index-sequentielle Dateizugriffsmethode. Eine ISAM-Datei kann wahlfrei, also mit Direktzugriff auf einen ganz bestimmten Satz, oder auch sequentiell vorwärts oder rückwärts verarbeitet werden. Dadurch entsteht ein enormer Geschwindigkeitsvorteil beim Suchen von Daten.

Um nun aber die ISAM-Macros verwenden zu können, muß man zuerst die PRIMA-Macros besitzen, da diese im Sourcecode des ISAM verwendet werden. Aus diesem Grund werden zunächst die Sourcelistings der PRIMA-Macros bei uns veröffentlicht.

Hinter dem Namen PRIMA verbirgt sich einfach mehr oder weniger der Name des Autors, da es die Abkürzung für Pritzen’s Machwerk darstellt. In PRIMA sind eine Menge an allgemeinen Macros und Standardroutinen vereinigt, die einem das Programmieren in Assembler vereinfachen sollen.

Das gesamte Macro-Paket ist in vier Teile mit folgenden Macromodulen unterteilt:

1. Allgemeine Macros

2. Diskettenmacros

3. Standardroutinen

  1. ISAM-Macros

In den ISAM-Macros wird die eigentliche Arbeit nicht durch die beiden Macros KEYLEN und ISAM geleistet, sondern durch die folgenden ISAM-Funktionsroutinen:

Nicht nur für Profis

Das gesamte Paket ist als Handwerkszeug für Assembler-Programmierer und für die, die bis jetzt nur flüchtigen Kontakt mit einem Assembler gehabt haben, gedacht. Es verkürzt die Arbeitszeit bei der Programmerstellung erheblich, befreit von vielen Routinearbeiten und läßt Raum für die Konzentration auf das eigentliche Programmierproblem .

Es soll hier weder ein Kurs in 68 000 Assembler abgehalten noch haarklein auch die letzte Feinheit der Anwendung erklärt werden. Ebenso wird vorausgesetzt, daß man sich mit seinem Assembler (etwas) vertraut gemacht hat. Man sollte also zumindest wissen, wie man ein Assembler-Sourcecode lädt, assembliert und wieder abspeichert. Die genauen Befehle mit ihrer Syntax kann man ja dem mitgelieferten Handbuch entnehmen, auch wenn es beim SEKA-Assembler etwas mager ausgefallen ist.

Dies alles soll Anfänger natürlich nicht abschrecken, sondern sie ganz im Gegenteil eher ermutigen. Gerade für den Beginner wird diese Macroroutinensammlung zum wertvollen Arbeitsmittel werden und den Einstieg in die Assemblerprogrammierung vereinfachen.

Wenn man am Anfang noch bei jedem kleinen Macro nachschlagen muß, so wird doch bald alles zur Routine, und man wird nur noch bei Besonderheiten nachlesen. Eine weitere Hilfe bei Fragen dürften die Macrodefinitionen und die Beispielprogramme liefern.

Zum eigentlichen Assembliervorgang sei folgendes gesagt. Man lädt zuerst den Sourcecode PRIMA.S, danach, falls das eigene Programm ISAM-Macros benutzt, ISAM.S und zuletzt das eigene Programm. Anschließend wird ganz wie gewohnt assembliert.

PRIMA gibt automatisch den nicht benötigten Speicherplatz an das GEM-DOS zurück. Hierfür ist unbedingt eine gerade Anzahl von Bytes des Gesamtprogramms erforderlich. Die GEMDOS-Funktion SETBLOCK ($ 4A) verursacht nämlich einen Totalabsturz, wenn eine ungerade Anzahl von Bytes vor liegt. Abhilfe kann man da leicht mit der EVEN-Instruktion schaffen, die zuletzt vor dem END angegeben werden muß.

Ein Stack von 300 Bytes wird von PRIMA automatisch eingerichtet. Wenn man mehr als diese 300 Bytes Stack benötigt, kann man wie gewohnt einen eigenen Stack am Anfang des Programmes einrichten. Andernfalls braucht man sich überhaupt nicht um den Stack zu kümmern, da er einfach vorhanden ist. Eine Ausnahme ist dann zu beachten, wenn man mit dem SEKA-Assembler Debugging betreibt. In diesem Falle muß die erste Instruktion des Programmes folgendermaßen lauten:

	START: LEA QSTACK+300,SP

Unter Debug startet man das Programm dann mit der G-Anweisung (in diesem Falle GSTART). Das Label START ist natürlich nicht zwingend, es kann auch ein anderer Labelname genommen werden. QSTACK darf nicht definiert werden, da PRIMA es schon gemacht hat.

Wenn das Programm fertig ausgetestet ist und selbständig ohne Debug laufen soll, kann die Anfangsinstruktion wieder entfernt werden. Falls man es vergißt, schadet es aber auch nichts.

Allgemeines zum Format

Ein Macromodul wird durch den Macronamen aufgerufen, dem, je nach Macro, eine bestimmte Anzahl an Parameter folgen. Folgende Parameter können zulässig sein:

Was für den Einzelfall gilt, kann man den Beispielen, den Macrobeschreibungen oder, was im Zweifelsfall am besten ist, den Macrodefinitionen selbst entnehmen.

Sowohl bei den Macros als auch bei den Standardroutinen bleiben die Registerstände unverändert; es sei denn, das betreffende Macro oder die Routine meldet in einem vereinbarten Register einen Rückkehrwert (z. B. einen Fehlercode). Eine Ausnahme bildet hier das Adressregister A0, das nach Beendigung des Macros bzw. der Routine einen anderen Inhalt haben kann.

Die Parameter

  1. Register

Sofern eine Registerangabe zulässig ist, wird der Inhalt des angegebenen Registers zur Verarbeitung herangezogen.

Beispiel: CHAR D5

Hiermit wird das im Register D5 enthaltene Zeichen auf den Bildschirm gebracht. Man muß bei der Registerangabe auf das Längenattribut achten, da die Registerdaten als Byte, Wort oder Langwort gefordert sein können.

  1. unmittelbare Daten

Unter unmittelbaren Daten versteht man z. B. # 12, d. h. die Zahl 12 wird verarbeitet.

Beispiel: GET 1,# 12,Dl

Der Datensatz mit der Nummer 12 wird aus der Datei 1 gelesen und anschließend an die in dem Datenregister Dl enthaltene Speicheradresse geschrieben.

  1. Label

Mit Label sind Marken gemeint, die irgendwo im Programm als Feldnamen definiert wurden. Das Doppelkreuz gibt hierbei an, daß die Adresse des Feldes und nicht der Inhalt benutzt wird.

Beispiel:

PRINTS # FELDl
FELDl: DC ”Ausgabetext”,0

Es wird der Text ausgegeben, der ab der Adresse FELDl im Speicher zu finden ist. In unserem Beispiel wird die Ausgabe dann beendet, wenn eine binäre Null gefunden wird.

  1. Label

Label ohne ein Doppelkreuz sind ebenfalls im Programm definierte Feldnamen, jedoch wird hier der Inhalt des Feldes und nicht seine Adresse angesprochen.

Beispiel: PUT 2, NUMMER,# PUFFER NUMMER: DC.L 4712 PUFFER: BLK 120

Es wird der Datensatz mit der Recordnummer 4712 in die Datei mit der Nummer 2 geschrieben und zuvor die Satzdaten ab der Adresse PUFFER geholt.

  1. ”Literal”

Hiermit sind in Anführungszeichen eingeschlossene, alphanumerische Werte gemeint. Überall, wo Literais zulässig sind, können niemals die Formen # Label oder Label Verwendung finden. Literais müssen immer zwischen zwei Anführungszeichen stehen.

  1. Funktionsnamen

Damit sind ganz bestimmte festgelegte Funktionsnamen für bestimmte Macros gemeint.

Beispiel: CONTROL CLS

CLS ist hier der Funktionsname für Bildschirm löschen (Clear Screen). So werden unter anderem alle CON-TROL-Sequenzen über solche Funktionsnamen aufgerufen.

Beispiel: ISAM 1,LESEN_R,#BUF1

Dieser Macroaufruf bewirkt, daß der nächstniedere Datensatz der als ISAM-

Datei organisierten Datei mit der Nummer 1 gelesen und anschließend ab Adresse BUF1 abgespeichert wird.

  1. Sonstige numerische Angaben

Dies sind numerische Angaben ohne irgendwelche Zusätze wie z. B. das Doppelkreuz #. Sie werden als Dateinummern (FAN), für Datensatzlängen und auch als Funktionsnummer beim GEMDOS-Macro verwendet.

Beispiel:

OPEN ’T” ,6,”MYFILE” ,120 READ 6,A5

Die Datei mit der Nummer 6, dem Dateinamen „MYFILE“ und einer Datensatzlänge von 120 Zeichen wird als Inputdatei eröffnet. Dann wird der nächste Datensatz aus dieser t)atei 6 ab der in dem Adressregister A5 stehenden Speicheradresse abgespeichert.

Dies soll zur Vorstellung zunächst einmal genug sein. Wir werden dann aber der nächsten Ausgabe mit den allgemeinen Macros der PRIMA-Bibliothek beginnen. (HE)

Um die Leistungsfähigkeit der beiden Modi zu verdeutlichen, geben wir hier als Beispiel eine Telefondatei.

START:	MOVE.L	DSKVEC.SAVEVEC :ADR.STANDARD-FEHLERROUTINE SAVEN

MQVE.L	»ERROR.DSKVEC ;ADR. EIGENE FEHLERROUTINE

OPEN	T",l, "PHONE.DAT". 52

AOOO:	MOVE.L	SAVEVEC,DSKVEC :A3 JETZT WIEDER ALTE ROUTINE

TST.L	D0	;ANDERER FEHLER ALS 'FILE NOT FQUND'?

BMI	ENDE	;JA, LEIDER

KEYLEN	1,#30

REPEAT	#10	;TASTENREPEAT AUF MITTELWERT

MOVE.W D7.SAVEREP	;ALTEN REPEAT-WERT RETTEN

MENUE:	CONTROL CLS

POS	#0.#5

PRINT	"ISAM-DEMOPROGRAMM TELEFONVERZEICHNIS"
PRINT	"COPYRIGHT (1986) BY	GERHARD	PRITZ	- BERLIN"

ZEILE

PRINTX	"DAS VERZEICHNIS	ENTHALT	"

MOVE.L	ISAM1+4.D1

MOVE.L	#REFE1.A2

JSR	BINASC

CLR.B	REFE1+1Q

PRINTS	»REFE1+5

PRINT	" EINTRÄGECONTROL	CUREIN

POS	*0;#10

PRINTS	#MENTXT

CONIN

JSR	LEEREN	;SYSTEMPUFFER TASTATUR LEEREN

:DENN WENN ER ÜBERLSUFT, WEIL IRGENDEIN ;	HIRN MIT SEINEM FINGER AN DER TASTE

;	KLEBT. STÜRZT DIE VERDAMMTE KISTE AB

CMP.B	#"1".D0

BEQ	DANF

CMP.B	#"2”.D0

BEQ	DEND

CMP.B	#"3".DQ

BEQ	SUCH

CMP.B	#"4",D0

BEQ	NEUER

CMP.B	#''5''. DO

BEQ	GLEICHH

CMP.B	#"6".D0

BEQ	GLEICHN

CMP.B	#"7",D0

BEQ	FIN

BRA	MENUE

DANF:	MOVE.B	*1,QM

DA000:	ISAM	1.LESEN,#BUF1

DA010:	CMP.B	*9.QF

BNE	ANZEIGE

PRINT	"•** DATEIGRENZE	ERREICHT	*****

DELAY	#5000.#300

BRA	MENUE

LEEREN:	MOVE.L	D0,-(SP)

LEER1:	INKEY

TST.L	D0

BNE	LEER1

MOVE.L	(SP)+,D0

RTS

DEND:	MOVE . B	#1. QM

DEOOO:	ISAM	1,LESEN_R,#BUF1

BRA	DA010

SUCH:	CONTROL	CLS

PRINT	"SATZ SUCHEN"

PRINT	»«**********•••

JSR	GETKEY

ISAM	1.SUCHEN.#BUF1

CMP.B	#2.QF

BNE	ANZEIGE

PRINT	"SATZ IST	NICHT	VORHANDEN"

DELAY	#5000,*300

BRA	MENUE

NEUER:	CONTROL	CLS

PRINT	"NEUEN SATZ EINFÜGEN"

PRINT	"+++++++++++++++++++"

N000:	JSR	GETKEY

ISAM	1,SCHREIBEN,#BUF1

CMP.B	#1 ,QF

BNE	NO 10

PRINT	"SATZ IST	SCHON	VORHANDEN"

BRA	N020

N010:	PRINTX	"WELCHE TELEFONNUMMER: "

MOVE.B	#15,D0

MOVE.L	#TELNR.A2

JSR	INPUT

ZEILE

TST.L	D0	;*C	?

BMI	NO 10	;JA

ADD.L D0.A2	;ADR.TELMR + LÄNGE DER EINGABE

NEG , L	DO

ADD.L	#15,D0	:15 - MAX.LÄNGE TELNR

FILL	A2.D0.#" "	.-RECHTSBÜNDIG MIT BLANKS FÜLLEN

CLR.B	LOE	;LOESCHMERKMAL

PUT	1,ISAMl.tBUFl ;NEUEN SATZ SCHREIBEN

N020:	ZEILE

PRINTX “WEITERE NEUEINGABE (J/N) ? "

CONIN

AND.B	#223,D0

CMP.B	#"J",D0

BNE	MENUE

BRA	NOOO

GLEICHH:	CONTROL	CLS

PRINT	"GLEICHEN ODER HÖHEREN SATZ SUCHEN"

PRINT ........................................

JSR	GETKEY

ISAM	1,GLEICH__HOCH, #BUF1

CMP.B	#9.QF	;EOF ?

BNE	ANZEIGE

GLH010:	PRINT	***** DATEIGRENZE	ERREICHT***"

DELAY	#5000.#300

BRA	MENUE

GLEICHN:	CONTROL	CLS

PRINT	“GLEICHEN ODER KLEINEREN SATZ	SUCHEN"

JSR	GETKEY

ISAM	l.GLEICH_TIEF,#BUFl

CMP.B	#9.QF	;EOF ?

BNE	ANZEIGE

BRA	GLHOIO

GETKEY:	POS	#0 #5

CONTROL	CCRESTB	;REST BILDSCHIRM LÖSCHEN

PRINTX	"NAME	: "

MOVE.B	#15,D0

MOVE.L	#QA.A2

JSR	INPUT

ZEILE

TST.L	D0

BMI	GETKEY	;CONTROL C UNERWÜNSCHT

BEQ	GETKEY	;EIN CHARACTER	SOLLTE ES SCHON SEIN

MOVE.L	tQA.Dl

ADD.L	D0,D1

NEG.B	DO

ADD.B	#15,D0

FILL	Dl,D0.#"	"

MOVE.L	#QA+15.A2

MOVE.B	#15,D0

PRINTX	"VORNAME: "

JSR	INPUT

ZEILE

TST.L	D0

BMI	GETKEY

RTS

ANZEIGE: CONTROL	CLS

CONTROL	CURAUS

PRINTS	#MENTXT2

TST.B	LOE

BEQ	ANOOO

PRINT	"*** GELÖSCHTER	SATZ ***"

ANOOO:	PRINTX	"NAME	: "

TRANSFER	#KEY1.#EUF2,#15

PRINTS	#3UF2

CHAR	#13

CONTROLM	CRECHTS, #35

PRINTX	"RECORD-# "

MOVE.L	I5AK1,Dl

MOVE.L	#REFE1.A2

JSR	BINASC

CLR.B	VORZ1

PRINTS	»REFE1+4

ZEI LE

PRINTX	"VORNAME : "

TRANSFER	#KEY2.#BUF2.#15

PRINTS	#BUF2

ZEILE

PRINTX	"TELEFON : "

PRINTS	#TELNR

AN010:	INKEY

TST.L	D0

BEQ	AN010

JSR	LEEREM	:REST DES	TASTENPUFFERS	LEEREN

AND.8	#223,D0	;DAMIT	ER	NICHT	UBERLÄUFT

CMP.B #"M",D0	;DENN SONST STÜRZT DER VOGEL AB

BEQ	MENUE

CMP.B	#"L",D0

BEQ	ANQ20

CMP.B	#“A",D0

BEQ	AN050

SWAP	DO

CMP.B	*$48,D0	;PFEIL LINKS

BEQ	DEOOO

CMP.B	#$4D,D0	:PFEIL RECHTS

BEQ	DAOOO

BRA	AN010

AN020:	TST.B	LOE

BEQ	AN040

CLR.B	LOE	;REAKTIVIEREN

AN03Q:	PUT	1,ISAM1.#BUF1

BRA	ANZEIGE

AN040:	MOVE.B #l,LOE	;LÖSCHEN

BRA	AN030

AN050:	TST.B	LOE

BNE	AN010	;WIR ANDERN NUR AKTIVE SATZE

CONTROL	CUREIN

PRINTX	“NEUE TELEFON-NR. :	*'

MOVE.B	#15,D0

MOVE.L	#TELNR.A2

JSR	INPUT

ZEILE

TST.L	D0

BMI	AN050

ADD.L	D0.A2

NEG.L	D0

ADD.L #15,D0	;RECHTSBÜNDIG BLANKS AUFFULLEN

FILL	A2,D0,#" -

BRA	AN030

ERROR:	CMP.L	#-33,D0	:FILE NOT FOUND ?

BEQ	E010

MOVE.L	SAVEVEC.A0

JMP	(A0)	;ZUR STANDARD-FEHLERROUTINE

E010:	CLR.L	D0

MOVE.L	SAVEVEC.DSKVEC

OPEN	"0".1."PHONE.DAT",52

BRA	AOOO

FIN:	CLOSE	1

ENDE:	REPEAT	SAVEREP	;ALTE REPEATSPEED WIEDER EINSTELLEN

GEMDOS	0

MENTXT:	DC	"	1	- DATEI ANFANG",13,10

DC	"	2	- DATEIENDE",13,10

DC	"	3	-SATZ SUCHEN",13,10

DC	"	4	- SATZ EINFUGEN",13,10

DC	"	5	- GLEICHEN ODER HÖHEREN SATZ SUCHEN",13,10

DC	"	6	- GLEICHEN ODER KLEINEREN SATZ SUCHEN",13,10

DC	"	7	- PROGRAMMENDE".13.10.10.10

DC	"	IHRE WAHL: ".0

KENTXT2:	DC	"	<- - VORANGEHENDER	SATZ",13,10

DC	"	->	- NÄCHSTER SATZ",13,10

DC	" TELEFONNUMMER ÄNDERN",13,10

DC	"	L	SATZ LÖSCHEN/REAKTIVIEREN",13,10

DC	"	M	- MENÜ".13.10.10.10.10.10.0

EVEN

SAVEREP:	DC.W	0

SAVEVEC:	DC.L	0

EVEN
BUF1:	BLK	6
KEY1:	BLK	15
KEY2:	BLK	15
LOE:	DC	0
TELNR:	BLK	15
DC	0
BUF2:	BLK	15
DC	0
EVEN END


Aus: ST-Computer 07 / 1986, Seite 14

Links

Copyright-Bestimmungen: siehe Über diese Seite