ISAM & PRIMA Teil 1 - Die allgemeinen Macros

Nachdem wir in der letzten Ausgabe die beiden Assembler-Macro-Modulbibliotheken ISAM & PRIMA vorgestellt haben, beginnen wir heute mit dem Abdruck der ersten Macro-Module von PRIMA. Es handelt sich dabei um die allgemeinen Macros. Auf Seite 27 werden noch die in den Macros benutzten Escape-Sequenzen aufgelistet, die an den Anfang des Macro-listings gestellt werden müssen.

DELAY:   MACRO
         MOVEM.L  D0-D1,-(SP)
         MOVE.W   ?1,D0
DEL1?O:  MOVE.W   ?2,D1
DEL2?0:  DBRA     D1,DEL2?0
         DBRA     D0,DEL1?0
         MOVEM.L  (SP)+,D0-D1 
         ENDM

DELAY
- Warteschleife

Dieses Macro besteht aus einer doppelten Warteschleife, d. h. beide Schleifen sind ineinander verschachtelt und werden auf -l heruntergezählt.

Beispiele: DELAY #3000,D1
DELAY #1000,# 500


REPEAT
- Wiederholungsrate der Tastatur festlegen

Bei diesem Macro sind Werte zwischen l und 20 zulässig, wobei l für schnell und 20 für langsam steht. Der alte Wert steht als Wort gespeichert im Datenregister D7.

Beispiel: REPEAT # 10

REPEAT:  MACRO
         MOVEM.L  D0-D6/A0-A6,-(SP)
         MOVE.W   #-1,-(SP)
         MOVE.W   #-1,-(SP)
         MOVE.W   #35,-(SP)
         TRAP     #14
         ADDQ.L   #6,SP
         MOVE.W   D0,-(SP)
         MOVE.W   ?1,D0
         CMP.W    #20,D0
         BGT      REP1?0
         CMP.W    #1,D0
         BLT      REP1?0
         MOVE.W   ?1,-(SP)
         MOVE.W   #$0F,-(SP)
         MOVE.W   #35,-(SP)
         TRAP     #14
         ADDQ.L   #6,SP
REP1?0:  MOVE.W   (SP)+,D7
         AND.W    #$FF,D7
         MOVEM.L  (SP)+,D0-D6/A0-A6
     ENDM

COMPARE
- Vergleichen zweier Felder

Format: COMPARE Feldl, Feld2, Länge

Die Felder Feldl und Feld2 können sowohl als Literal (z. B. „Egon") als auch als Register angegeben werden. Die Register AO, AI und DO dürfen allerdings nicht benutzt werden. DO kann aber als Längenregister verwendet werden. Nicht erlaubt sind Angaben wie #Feld. Wenn man die Form Literal verwendet, sollte die Längenangabe der Literallänge entsprechen.

Alle Register bleiben unverändert.

Der Vergleich erfolgt Bit für Bit von links nach rechts. Bei der ersten Ungleichheit wird abgebrochen.

Nach Ausführung des Macros kann der Bedingungsschlüssel genau wie bei der CMP-Assembler-Anweisung abgefragt werden. Die Abfrage bezieht sich dabei immer auf den zweiten Operanden.

Beispiele:
COMPARE Dl,"Name",#4
COMPARE "Franz",A2,D0
COMPARE #Feld,Dl,# 15 ist falsch, da #Feld nicht erlaubt ist.

COMPARE: MACRO
         MOVEM.L  DO-D1/AO-A1,-(SP)
         IF       '?1' > 'D7'
         BRA      COM2?0
COM1?0:  DC       '?1'
         EVEN
COM2?0:  MOVE.L   #COM1?0+1,AO
         ELSE
         MOVE.L   ?1,AO
         ENDIF
         IF       '?2' > 'D7'
         BRA       COM4?0
COM3?O:  DC       '?2'
         EVEN
COM4?0:  MOVE.L   #COM3?0+1,A1
         ELSE
         MOVE.L   ?2, A1
         ENDIF
         MOVE.L   ?3, D0
         SUBQ.L   #1, D0
         BMI      COM6?0
COM5?0:  MOVE.B   (A1)+,D1
         CMP.B    (A0)+,D1
         DBNE     D0.COM5?0
COM6?0:  MOVEM.L  (SP)+,D0-D1/A0-A1
         ENDM
GEMDOS:   MACRO
          MOVE     #?1 ,-(SP)
          TRAP     #1
          ADDQ.L   #2,SP
          ENDM

GEMDOS

Die Funktionsnummer wird als Parameter in Wortlänge auf den Stack gelegt und ein TRAP #1 mit anschließender Stackkorrektur durchgeführt.

Beispiel:
GEMDOS 0 ;Rückkehr zum Desktop


CONIN:   MACRO
         MOVE.W   #1,-(SP)
         TRAP     #1
         ADDQ.L   #2,SP
         ENDM

CONIN
- Eingabe eines Zeichens von Tastatur mit Warten

Die Routine wartet, bis ein Zeichen über die Tastatur eingegeben wird. Das Ergebnis steht anschließend im Datenregister D0, wobei das untere Byte des Low Words den ASCII-Code und das untere Byte des High Words den Scan-Code der gedrückten Taste enthalten.

So ist der Inhalt von DO nach Betätigen der Backspace-Taste 00E 0008.


INKEY

Diese Routine wartet - im Gegensatz zum CONIN-Macro - nicht auf die Eingabe eines Zeichens, sondern überprüft nur, ob eine Taste gedrückt wurde. Man kann sie also gut als Abfrage in einer Schleife einsetzen. Das Ergebnis steht ebenfalls im Datenregister DO. Ist keine Taste gedrückt worden, steht in DO eine Null.

INKEY:   MACRO
         MOVE.W   #$FF,-(SP)
         MOVE.W   #6,-(SP)
         TRAP     #1
         ADDQ.L   #4,SP
         ENDM

CONTROL
- Ausgabe von Control-Anweisungen an den Bildschirm

Für die Ausgabe von Control-Anweisungen an den Bildschirm werden die am Anfang als Equates definierten

Escape-Sequenzen benötigt. Sie werden einfach als Funktionsnamen zur Bildschirmsteuerung benutzt.

Beispiel: CONTROL CUREIN ;Cursor einschalten

CONTROL: MACRO
MOVE.L
MOVE
MOVE
TRAP #1 MOVE
MOVE
TRAP
ADDQ.L
MOVE.L
ENDM
D0,-(SP)
#27, -(SP)
#2,-(SP)
#1
#?1 ,-(SP)
#2,-(SP)
#1
»8 ,SP
(SP)+,D0

CONTROLM
- Mehrfache Ausgabe derselben Control-Anweisung

Das CONTROLM-Macro wird im Prinzip genauso aufgerufen wie das CONTROL-Macro. Der einzige Unterschied besteht darin, daß man noch zusätzlich als Parameter die Anzahl der Aufrufe derselben Control-Anweisungen angeben muß.

Alle Register bleiben unverändert.

Beispiel:

CONTROLM CRECHTS,# 15 ;Cursor 15 Stellen nach rechts

CONTROLM: MACRO
MOVEM.L
MOVE.W
SUBQ.W
BMI
MOVE
MOVE
TRAP #1
MOVE
MOVE
TRAP
ADDQ.L
DBRA
MOVEM.L
FMDM
DO-D1/AO, -(SP)
?2,D1
#1,01
CON27O
CONI70: #27, -(SP)

#2,-(SP)
#1
#71 ,-(SP)
#2,-(SP)
«t
#8,SP
Dl ,CON1?0
CON270: (SP)+,00- Dl XftO

CHAR
- Ausgabe eines Zeichens an der aktuellen Cursorposition

Das Zeichen darf entweder als Literal (z. B. „A") oder auch als Wort (.W) in einem Register vorliegen. Nicht zulässig ist die Form #Label.

Beispiel: CHAR #"A"

     TRAP     #1
CHAR MACRO
MOVE L D0,-(SP)
MOVE ?1 , -(SP)
MOVE #2,-(SP)
ADDQ L #4,SP
MOVE L (SP)+,D0
ENDM

POS
— Positionierung des Cursors

Um den Cursor auf dem Bildschirm zu positionieren, müssen Zeile und Spalte als Parameter angegeben werden. Dabei können unmittelbare Werte oder auch Register angegeben werden.

Beispiel: POS #0,#15

;Spalte 0, Zeile 15

POS:

MOVE.L

MOVE

MOVE

     TRAP     #1

MOVE

MOVE

TRAP

MOVE

ADD

MOVE

     TRAP     #1

MOVE

ADD

MOVE

     TRAP     #1

ADD. L

MOVE.L


MACRO

00,-(SP)

#27, -(SP)

#2,-(SP)

#1

#-Y-,-(SP)

#2,-(SP)

#1

?2,-(SP)

#32, (SP)

#2,-(SP)

#1

?1 ,-(SP)

#32, (SP)

#2,-(SP)

#1

#16,SP

(SP)t,D0

ENDM

TRANSFER
- Übertragen von Daten

Format: Anfangsadr. Sendefeld, An-fangsadr. Empfangsfeld, Länge

Außer den Registern AO, AI und DO können auch beliebige Register angegeben werden. DO darf jedoch als Längenregister genutzt werden.

Das schöne an diesem Macro ist, daß es sich um ein „intelligentes" Macro handelt. Damit ist gemeint, daß sich die zu übertragenden Felder auch überlappen dürfen. Ein Feld kann somit z. B. auch nur um einige Stellen nach links oder rechts verschoben werden. Wenn als Länge eine Null in DO steht, findet kein Transfer der Daten statt.

Beispiel:

TRANSFER # Feldl + 2,# Feld2,# 20

Achtung: Bei einem Aufruf nach dem dritten Parameter sofort die RETURN-Taste drücken und keine Remarks (;) auf derselben Zeile machen.

Begründung: Im Macro wird mit IF abgefragt, ob DO Längenregister ist. Wenn Remarks dem dritten Parameter folgen, so werden diese als Bestandteil des dritten Parameters mit einbezogen, so daß „DO" < > „DO; Remark" wird. (Dies ist offensichtlich eine Eigenart der benutzen Macro-sprache).

TRANSFER: MACRO
MOVEM.L DO/AO/A1 ,-(SP)
MOVE.W ?3,D0
SUBQ.W #1 ,D0
BMI TR470+4
MOVE . L ?1 , AO
MOVE.L ?2,A1
CMP.L AO, AI
BPL TR270
TR170: MOVE. B (A0)-t-, (AI > +
DBRA D0,TR1?0
BRA TR470+4
TR270: ADD.L 73, A0
ADD.L 73, A1
IF "73' = "D0"
ADDQ.L #1 ,A0
ADDQ.L «1 ,A1
ENDIF
TR370: MOVE. B -(A0), -(AI)
TR470: DBRA D0,TR3?0
MOVEM.L (SP)t,D0/A0/A1
ENDM

FILL
— Füllen eines Feldes

Format: FILL Adresse, Länge, Füllzeichen

Es dürfen bei diesem Macro alle Register außer DO und AO benutzt werden. DO darf wiederum Längenregister sein. Die Register werden nicht verändert.

Beispiel: FILL#Feld,#1000,#" "
; 1000 Blanks werden ab Adresse
; #Feld geschrieben.

FILL: MACRO
MOVEM.L D0/A0.-(SP)
MOVE.W 72,00
SUBQ.W #1 ,D0
BMI FI270+4
MOVE.L 71 , A0
FI 170: MOVE. B 73, ( A0)+-
FI270: DBRA D0,FI 170
MOVEM.L (SP)+,D0/A0
ENDM
PRINT:   MACRO
         MOVE.L  D0,-(SP)
         BRA     PRX2?0
PRX1?0:  DC      ?1,13,10,0
         EVEN
PRX2?0:  MOVE.L  #PRXl?0,-(SP)
         MOVE    #9,-(SP)
         TRAP    #1
         ADDQ.L  #6,SP
         MOVE.L  (SP)+,D0
ENDM

PRINT
- Textausgabe auf Bildschirm mit Carriage Return (CR) und Line Feed (LF)

Dieses Macro entspricht dem PRINT-Befehl in Basic. Der Text darf keine Kommata enthalten. Zur Ausgabe von Kommata des PRINTS-Macro verwenden. Alle Register bleiben unverändert.

Beispiel: PRINT "Hallo Welt!!!"



PRINTX:  MACRO
         MOVE.L  D0,-(SP)
         BRA     PR2?0
PRX1?0:  DC      ?1,0
         EVEN
PRX2?0:  MOVE.L  #PRl?0,-(SP)
         MOVE    #9,-(SP)
         TRAP    #1
         ADDQ.L  #6,SP
         MOVE.L  (SP)+,D0
ENDM

PRINTX
- Textausgabe auf Bildschirm ohne CR und LF

Für dieses Macro gelten die gleichen Bedingungen wie für das PRINT-Macro.

Beispiel: PRINTX "Kein Carriage Return und Line Feed"


PRINTS
- Speicherinhalt auf Bildschirm ausgeben

Mit diesem Macro können beliebige Speicherinhalte auf den Bildschirm ausgegeben werden. Das entsprechende Datenfeld muß mit "00" abgeschlossen sein. Es dürfen auch Register benutzt werden. Die Registerinhalte werden nicht verändert.

Beispiel:

PRINTS #Feld l Feldl: de "Ausgabetext",13,10,0 ; 13 = CR 10=LF

MOVE.L D0,-(SP)
PRINTS: MACRO
MOVE. L

71 , -(SP)

MOVE #9,-( SP)
TRAP #1
ADDQ. L #6,SP MOVE.L (SP) + ,00
ENDM

ZEILE
- Zeilenvorschub

Dieses Macro bewirkt ein Carriage Return und Line Feed, so daß auf dem Bildschirm in eine neue Zeile gegangen wird.

Beispiel: ZEILE

Damit erst einmal genug für den ersten Teil des Sourcecode-Listings. In der nächsten Ausgabe werden wir dann den zweiten Teil - die Disket-tenmacros — abdrucken und dokumentieren.

MOVE.L D0,-(SP)
ZEILE: MACRO
MOVE #1 3 , -(SP)
MOVE #2, -(SP)
TRAP #1
MOVE #10 ,-(SP)
MOVE #2, -(SP)
TRAP #1
ADDO.L #8, SP
MOVE.L

(SP)+,D0

ENDM

; Escape-Sequenzen

NLIST
CHOCHO : EQU 65 ;#"A- CURSOR HOCH OHNE NEGATIVES SCROLLING
CTIEF: ES U 66 ;#'B- CURSOR RUNTER
CRECHTS: EQU 67 ;*"C" CURSOR RECHTS
CLINKS: EQU 68 ;#"D" CURSOR LINKS
CLS: EQU 69 ;#•£• CLEAR THE SCREEN, CURSOR HOME
CHOME: EQU 72 ;#"H" CURSOR HOME OHNE CLEAR SCREEN
CHOCH: EQU 73 ;#-!• CURSOR HOCH GGF. MIT NEGATIVEM SCROLL
CCRESTB: EQU 74 ;<TJ- REST DES SCHIRMS AB AKT. POS (EINSCHL . ) LOSCHEN
CZEILEND: EQU 75 ;<TK" REST DER ZEILE AB AKT. POS < EINSCHL.) LÖSCHEN
CZEILREIN :EQU 76 itt-L," LEERZEILE EINFÜGEN
CZEILRAUS :EQU 77 ;#-M" ZEILE LÖSCHEN «ANDERE ZEILEN WERDEN RANGERÖCKT)
CBISC: EQU 100 ;#-d* CLEAR BILDSCHIRM BIS CURSORPOSITION
CUREIN: EQU 101 ;#-e- CURSOR EIN
CURAUS: EQU 102 ;#-f CURSOR AUS
CURSPEI : EQU 106 ;#"j- CURSORPOSITION WEGSPEICHERN
CURSET: EQU 107 ;#-k" CURSOR AUF GESPEICHERTE POS SETZEN (SIEHE J)
CZEI L : EQU

108 ;#"!• ZEILE LÖSCHEN CANDERE ZEILEN UNBEEINTRÄCHTIGT)

CZEILANF: EQU

111 ;#'o" ZEILE BIS (EINSCHL.) CURSORPOS LÖSCHEN

CREVEIN: EQU 112 ;#-p- INVERTIERTE AUSGABE EIN
CREVAUS: EQU 113 ;#"q- INVERTIERTE AUSGABE AUS
CAUTOEIN: EQU 118 ;#-v" AUTOM. OBERLAUF AM ZEILENENDE EIN
CAUTOAUS: EQU 119 ;#"w- AUTOM. ÜBERLAUF AM ZEILENENDE AUS


Aus: ST-Computer 09 / 1986, Seite 24

Links

Copyright-Bestimmungen: siehe Über diese Seite