APPLICATIONSPROGRAMMATION ★ Der gläserne Assembler|CPC Magazin) ★

KIO-FOX-AssemblerApplications Programmation
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Der KIO- Fox-Assembler ist in Basic geschrieben. Seine Funktionen sind daher leicht nachvollziehbar.

Das hier vorgestellte Programm besitzt folgende Merkmale:

  • Z80-Assembler, voller Sprachumfang, erweitert
  • erzeugt Object-Code-Dateien für jede Stelle im RAM (oder ROM)
  • Quelldatei-Länge unbegrenzt
  • ca. 25 KByte für Label-Tabelle (Version ohne REMs)
  • Verkettung von Quelldateien über CAT-Pseudo-Opera-tion
  • bedingte Assemblierung mit praktisch unbegrenzter Schachteltiefe
  • Quelldateien beliebig mit oder ohne Zeilennummern
  • TABs und Leerzeichen sind gleichwertig und meist überflüssig
  • numerische Konstanten beliebig nach M80- oder GE-NA3-Standard
  • Doppel-':' wird überlesen (für M80-Freunde)
  • arithmetische Ausdrücke mit + - * / modulo and or xor > >= < <= < > =
  • weiche Label-Deklaration mit 'DEFL' möglich

Der Assembler ist als 2-Pass-Version realisiert und liest die Quelltexte grundsätzlich von Diskette bzw. Cassette ein. Bei Cassetten-Assemblierung muß man deshalb das Band vor Pass 2 zurückspulen. Außerdem kann es bëi langen Programmen Vorkommen, daß Teile des erzeugten Maschinencodes bereits während Pass 2 gespeichert werden. Dann ist bei Cassettenbetrieb auf die Meldungen des CASS-Managers zu achten.

Das Programm ist ganz in Basic geschrieben. Man darf deshalb von seiner Verarbeitungsgeschwindigkeit keine Wunder erwarten. Dennoch ist es erstaunlich flott, und der Einsatz dieser Sprache hat den Vorteil, daß Sie seine Wirkungsweise leicht nachvollziehen und eventuell eigene Änderungen daran vornehmen können. Ansonsten erfüllt das Programm alle Ansprüche, die man an einen Z80-Assem-bler stellen kann (sogar noch ein paar mehr).

Mit Remark-Zeilen ist der Assembler etwas über 17 KByte lang, ohne alle REMs und überflüssigen Leerzeichen ca. 12 KByte. Er arbeitet in zwei Durchgängen, wobei in Pass 2 eine Ausgabe auf einem Drucker möglich ist. Als Textquelle werden grundsätzlich nur Text-Files vom Massenspeicher (Cassette oder Diskette) eingelesen; hier lassen sich über eine Pseudo-Operation praktisch beliebig viele Dajteien verketten. Der Maschinencode wird in Pass 2 direkt auf den Massenspeicher geschrieben, wobei mit einem Trick gleich ein Binärfile-Header erzeugt wird. Im RAM stehen derweil ca. 25 KByte für Labels zur Verfügung. Der Assembler kann Maschinencode für jede Stelle im RAM (oder ROM) erzeugen!
Zusätzliche Operationen des Assemblers

1. Illegals

IX Prefix IX (um z.B. die Illegals LD A, XH o.a. zu bilden)
IX = Illegal: LDA.XH LD A, H
IY Prefix IY (entsprechend)
SLL r Shift Left Logical: Bits nach links schieben und Bit 0 setzen
r = B, C, D, E, H, L, A, (HL), (IX+ofs), (IY+ofs)

2. Zusätzliche Word-Lade-Befehle

LD dd, dd Sie werden realisiert durch die jeweils zugehörigen Byte-Ladebefehle:
LD BC, DE = LD B, D
                   LD C, E
dd = BC, DE, HL

3. CPC-typische Befehle

JP LOW, nnnn RST 1 & DEFW nnnn
CALL SIDE, nnnn RST 2 & DEFW nnnn
CALL FAR, (nnnn) RST 3 & DEFW nnnn
LAM A, (HL) RST 4
JP FIRM, nnnn RST 5 & DEFW nnnn

4. Ausgeweitete Syntax für einige Befehle

Sie dient dazu, häufige Flüchtigkeitsfehler abzufangen. Wahlweise:

  • ADD A,xyz = ADD xyz
  • ADC A,xyz = ADC xyz
  • SUB A,xyz = SUB xyz
  • SBC A,xyz = SBC xyz
  • XOR A, xyz = XOR xyz
  • OR A,xyz = OR xyz
  • AND A,xyz = AND xyz
  • CP A,xyz = CP xyz
  • EX AF,AF' = EX AF', AF
  • EX DE, HL = EX HL, DE
  • EX (SP), HL = EX HL, (SP)
  • EX (SP), IX = EX IX, (SP)
  • EX (SP), IY = EX IY, (SP)

5. Anpassung an Inkompatibilitäten einiger Assembler

Wahlweise:

  • RST 0 = RST 0
  • RST 1 = RST8
  • RST 2 = RST16
  • RST 3 = RST 24
  • RST 4 = RST 32
  • RST 5 = RST 40
  • RST 6 = RST 48
  • RST 7 = RST 56
  • IM 0 = IM0
  • IM 1 = IM1
  • IM 2 = IM2

Unmittelbare Argumente

Unmittelbar anzugebende Argumente (z.B. in LD HL, nnnn) können aus Zahlen und Labels bestehen und lassen sich über Operatoren verknüpfen, die von links nach rechts abgearbeitet werden. Alle Rechenoperationen arbeiten mit vorzeichenbehafteten Words (Integer) und sind mit &FFFF maskiert, um sie gegebenenfalls wieder in den Darstellungsbereich zu zwingen. Ein Überlauf bei der Verknüpfung von Word-Konstanten kann daher nicht auftreten. (Allerdings dürfen die Konstanten selbst den Integer-Bereich nicht überschreiten!)

Operatoren

Für sie sind folgende Sonderzeichen vorgesehen.

+ - * / Addition/Subtraktion/Multiplikation/Division
\ & ? ! Modulo/AND/OR/XOR
> = < >= <= < > Vergleiche
- + Vorzeichen

Vorzeichen

Sie können vor Zahlen und Labels gesetzt werden. (Einzige Ausnahme: Nach IY und IX darf nach den Operatoren + oder - kein Vorzeichen folgen!)
LD HL, anton + -&80 o.k.
LD A, (anton*-10) o.k.
LDA,(IX+anton+-10) o.k.
LDA, (IX+-10) geht nicht

Labels

Sie beginnen immer mit einem Buchstaben und können danach mit so ziemlich allem weitergehen, was kein Operator oder Separator ist. Unter anderem sind deshalb auch der Unterstrich (_) und der Punkt möglich! Groß- und Kleinschreibung werden nicht unterschieden.

Zahlen

Sie beginnen immer mit einer Ziffer bzw. # für Hex- oder % für Binär-Darstellung. Zusätzlich ist der M80-Standard mit H bzw. B als Postfix für Hex- und Binär-Zahlen möglich. 12345 dezimal 1234H hexadezimal %10101 binär OFFFFH hexadezimal 10101B binär +FFFF hexadezimal Zeichenketten

Es können auch ein oder zwei Byte lange Zeichenketten verwendet werden.

LD A, ”x” o.k.
LD HL, ”xy” o.k.
LD A, ”ab” geht nicht
LD HL, ”abc” geht nicht

Pseudo-Operationen

ORG < ausdruck >
Origin-Anweisung. Der Ausdruck muß in Pass 1 bestimmbar sein. Der Assembler kann Maschinencode für jede Stelle im RAM bzw. ROM erzeugen. Ist kein Origin angegeben, wird ORG 0 angenommen!

END
Ende des Quelltextes. Dies ist zwar nicht unbedingt notwendig, kann aber benutzt werden, um innerhalb eines bedingten Abschnitts die Assemblierung zu beenden.

IF < ausdruck >
Beginn eines bedingten Abschnitts im Quelltext. Der Ausdruck muß bereits in Pass 1 bestimmbar sein. Die folgenden Zeilen werden nur bearbeitet, wenn der Ausdruck ungleich 0 und die Assemblierung nicht auch noch durch übergeordnete IFs ausgesetzt ist. Bedingte Abschnitte können praktisch beliebig tief geschachtelt werden (255 Ebenen). Der Ausdruck muß nur dann bestimmbar sein, wenn die bedingte Assemblierung gerade eingeschaltet ist.

ELSE
Schaltet Bedingung der letzten Schachteiebene um.

FIN
Bezeichnet das Ende der letzten Schachtelebene.

DEFB
Define Byte. Es können beliebig viele Byte-Ausdrücke folgen.

DEFW
Define Word. Es können beliebig viele Word-Ausdrücke folgen.

DEFM
Define Message. Es können beliebig viele, beliebig lange Text-Ausdrücke folgen. Diese müssen in Gänsefüßchen eingeschlossen werden. Folgende Zeichen besitzen Sonderfunktionen:
^x -> Controlcode: CHR$ (ASC (x) AND 31)
\x -> Zeichen x: nicht als Steuerzeichen auswerten
|x -> Zeichen x mit gesetztem Bit 7: (CHR$ (ASC (x) OR &80)

DEFS < ausdruck >
Define Space. Bestimmt die Länge eines Bereichs, der mit Null-Bytes gefüllt wird. Der Ausdruck muß bereits in Pass 1 bestimmbar sein.

DEFS < ausdruck1 >, < ausdruck2 >
Define Space. Zusätzlich ist angegeben, mit welchem Byte (= ausdruck 2) der Bereich gefüllt werden soll; ausdruck 2 muß natürlich erst in Pass 2 bestimmbar sein.

CAT < dateiname >
Fortsetzung des Assembler-Textes in einer anderen Datei; die aktuelle wird geschlossen.

Label-Definitionen
< name >:............ Harte Wertzuweisung für ein
< name >::............ Label, das in Pass 1 mit dem aktuellen Wert des Programmzeigers '$' definiert wird.
< name >:EQU < ausdruck > Harte Wertzuweisung für ein
< name >:: EQU < ausdruck > Label. Der Ausdruck wird in Pass 1 ausgewertet.
< name >:DEFL < ausdruck > Weiche Wertzuweisung für ein
< name >:: DEFL < ausdruck > Label. Der Ausdruck wird in

Pass 1 und Pass 2 ausgewertet. Die Änderungen sind erst nach der (Um-) Definition gültig. Labels fangen immer mit einem Buchstaben an. Alle Zeichen sind signifikant!

Harte Label-Definitionen

Hier darf das Label nur einmal festgelegt werden. Dabei sind Vorwärts-Bezüge möglich (Benutzung des Labels im Programmtext, bevor es definiert wurde):

LOOP1: CP (HL) ; <---.
INC HL ;                    |
JR NZ, LOOP1 ;  ------'

Ein Label kann allerdings auch mehrfach mit demselben Wert definiert werden.

Weiche Label-Definitionen

Hier darf das Label sukzessive umdefiniert werden, z.B. für die Zuweisung von Variablen-Plätzen:

...
GLOB: DEFL # A000 ; Start der globalen Variablen (nicht mit EQU!)
AKKU: EQUGLOB ; Platz für Real-Variable
AKKU reservieren GLOB: DEFL GLOB+ 5 ; benötigt 5 Byte Platz
BREG: EQUGLOB ; Platz für Real-Variable
BREG reservieren GLOB: DEFLGLOB + 5 ; benötigt auch 5 Byte Platz

Der Assembler überprüft bei jeder Label-Definiton, ob sie zulässig ist. Existiert bereits ein gleichnamiges Label, so kann nur ein mit DEFL weich definiertes Label wieder mit DEFL weich umdefiniert werden!

Anforderungen an den Quelltext

Das Programm liest den Quelltext zweimal ein. Bei Cassettenbetrieb muß deshalb vor Pass 2 zurückgespult werden. Es akzeptiert nur normale ASCII-Dateien.

Jede Assembler-Zeile darf maximal 250 Zeichen umfassen und besteht aus den folgenden vier Teilen, wobei jeder fehlen kann. Im Extremfall sind auch Leerzeilen zulässig.

0. Zeilen-Nummer.
1. Label-Feld, wird mit abgeschlossen.
2. Z80- oder Pseudo-Operation, wird mit Space, TAB, Semikolon oder Zeilen-Ende abgéschlossen.
2.1 .Argument, wird mit Komma, Semikolon oder Zeilen-Ende abgeschlossen.
2.2 Letztes Argument, wird mit Semikolon oder Zeilen-En-de abgeschlossen.
3. Bemerkung, beginnt mit Semikolon, wird mit Zeilen-Ende abgeschlossen.

Arbeit mit dem Assembler

Zunächst wird eine Textdatei mit einem Assembler-Programm geschrieben. Dazu kann man eine Textverarbeitung benutzen: es ist aber auch möglich, den Zeileneditor des Basic-Interpreters einzusetzen. In diesem Falle schreibt man den Assembler-Text wie ein Basic-Programm, das dann nur mit der A-Option gespeichert werden muß (z.B. SAVE "linecopy.asc”, a).

Ist sein Quelltext erstellt und auf Diskette bzw. Cassette gesichert, lädt man den Assembler und startet ihn mit: RUN "assemblr.go"

Er frägt nun nach dem Namen der Quelldatei mit dem As-sembler-Programm und dem Namen, unter dem der Maschinencode abgespeichert werden soll. Außerdem kann man die Ausgabe des Listings in Pass 2 (2. Durchgang) auf den Druckér umlenken und bestimmen, ob der Assembler bei Fehlern auf einen Tastendruck warten soll. Arbeitet man mit Cassetten, muß man vor Pass 2 zurückspulen, damit der Assembler die Quelldatei erneut durchlesen kann.

Nach Abschluß von Pass 2 wird der Maschinencode unter dem angegebenen Namen auf Diskette (Cassette) gespeichert. Ist der erzeugte Maschinencode länger als 1920 Byte, wird er bereits während Pass 2 stückweise gespei-
chert. Bei Verwendung von Cassetten sind diese dann zu wechseln (Meldungen des CASS-Managers beachten!).

Der Maschinencode kann nun in der üblichen Weise geladen werden, von einem Basic-Programm aus z.B. mit: ORG 40000 —-> MEMORY 39999 : LOAD "mcode”

Der Assembler gibt außerdem Startadresse und Länge des erzeugten Maschinencodes aus und ferner eine Warnung, wenn nicht alle IF-Pseudo-Operationen mit FIN abgeschlossen wurden. Den Abschluß bildet ein Dump aller verwendeten Labels, wie sie der Assembler intern abgespeichert hatte. Bei Syntax-Fehlern generiert er automatisch:

RST 6
NOP
NOP
NOP

Dies erlaubt in den meisten Fällen, mit einem Monitor-Programm nachträglich noch den korrekten Code einzuarbeiten. Bei unbekannten Labein wird der Wert 0 eingesetzt.

Gliederung des Programms

  • 1000-1410 Allgemeine Initialisierungen
  • 1420-1550 Erster Durchgang (Pass 1)
  • 1540-1680 Zweiter Durchgang (Pass 2)
  • 1690-1750 Vorbereitende und abschließende Operationen, die in Pass 1 und 2 identisch sind
  • 1760-1850 Bearbeiten einer Assembler-Zeile Ein- und Aussprung: Zeile  1390 —> Zeile einiesen, Auswertung aufrufen, aus-drucken, Fehler mitzählen, Code speichern, poken
  • 1860-2180 Eine Assembler-Zeile bearbeiten —> Zeilennummer überspringen, Label-Definition behandeln (Aufruf eines Unterprogramms), Test auf Pseudo-Operation und bedingte Assemblierung, Separieren der Argumente einer Z80-0peration. Verzweigung entsprechend Anzahl Argumente und Operations-Name zur Behandlungsroutine
  • 2190-3820 Behandlungsroutinen für die verschiedenen Operationen mit einem oder zwei Argumenten
  • 3830-4400 Unmittelbare (konstante) Argumente bestimmen: Byte, Word (Adresse), Distanz und Offset zu IX/IY
  • 4410-4520 Ein Argument aus der aktuellen Zeile separieren
  • 4530-4720 Test auf Argument in Klammern, Test auf Indexregister, Force Integer
  • 4730-4840 Fehlermeldungen
  • 4850-5480 Behandlung von Pseudo-Operationen
  • 5490-5800 Label-Definition, Label suchen

Variablenliste

nq$ Name der (ersten) Quelldatei
nz$ Name der Zieldatei (Maschinencode-Datei)
l$(50) Label-Sammler (Namen und Wert)
Im Letzter belegter Index bei l$()
Io List Output: Stream-Nummer für Listing
(0=Screen, 8=Drucker)
p1,p2 Flags für Pass 1 oder Pass 2 org Origin des Assembler-Programms hi Start des real benutzten Bereichs im RAM (unter HIMEM)
pz Programmzeiger im Assembler-Programm relativ zu org bzw. hi platz Länge des unter HIMEM reservierten Bereichs errors Zähler der aufgetretenen Fehler
cond$ Sammler für bis zu 255 verschachtelte IFs
cf Flag, das anzeigt, ob alle verschachtelten IFs erfüllt sind
t$ Text, der im Assemblerlisting ausgegeben werden soll
z$ (Rest der) aktuell bearbeitete(n) Assembler-Text-zeile
er$ Fehlermeldung
b$ Hex-Darstellung des zu erzeugenden Codes einer Textzeile m$ (Pseudo-) Operation
a$ Zweites oder einziges Argument einer Operation
arg1$ Erstes Argument einer Operation bei zwei Argumenten
i, j, k Allround-Variablen der Routinen bis Zeile 3820
kl Flag, ob Argument in Klammern steht
nn Wert von unmittelbaren Ausdrücken (Adressen, Offsets usw.) ii Flag für IX+ofs oder IY+ofs
m, n, o, p Allround-Variablen der Routinen von 3830 bis 4720
nn!, d! Hilfsvariablen für Werte, die zu groß sein könnten
d$ Ein Operator (Zahl oder Label, eventuell mit Vorzeichen) aus a$ l$ Einzutragendes Label

Günter Woigk , CPC Magazin

★ PUBLISHERS: CPC Magazin , CPC Magazin Codex
★ YEAR: 1987
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LICENCE: LISTING
★ AUTHOR: Günter Woigk

★ AMSTRAD CPC ★ DOWNLOAD ★

File:
» KIO-FOX-Assembler  v1.1DATE: 2015-07-24
DL: 62 fois
TYPE: ZIP
SIZE: 35Ko
NOTE: 40 Cyls
.HFE: OUI

Je participe au site:
» Newfile(s) upload/Envoye de fichier(s)
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Prospero Software Pro Fortran
» Applications » WACCI Programmers' Patch disc
» Applications » Initiation au Basic Amstrad
» Applications » Nevada Basic
» Applications » Arrays variabel dimensioniert
» Applications » Verschiedene Schiftarten erzeugen (CPC Amstrad International)

QUE DIT LA LOI FRANÇAISE:

L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!

CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 146 millisecondes et consultée 750 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.