ACME

Aus C64-Wiki
Zur Navigation springenZur Suche springen
ACME
Firma Smørbrød Software
Entwickler Marco Baye
Verleger Freeware
(Der aktuelle Sourcecode)
aktuelle Version 0.97 (Source)
Release 2003
Lizenz GNU General Public License
Plattform AmigaOS bzw. MorphOS, DOS, Linux/Unix,
RISC OS und Windows
Bedienung Icon tastatur.png
Sprache Sprache:englisch
Information Crossassembler

ACME ist ein kostenloser Crossassembler, der für mehrere Plattformen erhältlich ist. Das Programm ist unter der GNU General Public License erstellt und unterstützt 6502, NMOS6502 (d.h. mit "illegalen" Opcodes), 65c02, Rockwell 65c02, WDC 65c02, 65CE02, 4502, MEGA65 und 65816 Prozessoren.

Der Assembler kann mit dem Programm Relaunch64 von Daniel Lüdecke zusammen verwendet werden.

Ursprünglich wurde ACME unter RISC OS erstellt mit der Idee, dass es auch eine Version für den C64/C128 geben soll. Inzwischen gibt es zwar Portierungen auf viele Plattformen, aber immer noch keine C64-/C128-Version. Da der Sourcecode in Standard-C vorliegt, sind Portierungen leicht machbar. Insbesondere auf allen Linux-Varianten und anderen Unix-artigen Systemen ist ACME problemlos kompilierbar.

ACME hat einen Parser für mathematische Ausdrücke implementiert, der komplexe Berechnungen durchführen kann, z.B. um Sinustabellen zu erstellen.

Empfohlen wird die Endung ".a" als Dateierweiterung für ACME-Quelldateien. ACME kann mit unterschiedlichen Zeilenenden-Konventionen im Quellcode umgehen, akzeptiert nur-CR, nur-LF oder CRLF. Die Relaunch64-Umgebung bringt ein Icon mit, das mit dem Quelldateityp verbunden werden kann.

Alle Schlüsselwörter beschränken sich auf 7-Bit-ASCII, aber für Namen eines Labels sind auch 8-Bit-Zeichen erlaubt, was bei Quellcodedateien verschiedener Plattformen eigenartig aussehen kann.


ACME-Library[Bearbeiten | Quelltext bearbeiten]

Die Dateien im Verzeichnis ACME_Lib können mit Hilfe der Pseudo-Befehle "!source" oder "!binary" in den Quellcode eingebunden werden.

  • Dateinamen im Format "..." werden im aktuellen Verzeichnis, wo ACME aufgerufen wird, gesucht. Über den CLI-Switch "-I" können auch zusätzliche Suchpfade angegeben werden.
  • Dateinamen im Format <...> werden in einem speziellen Library-Verzeichnis gesucht. Um dieses Verzeichnis zu finden, muss auf den meisten Plattformen die Umgebungsvariable "ACME" richtig gesetzt werden. Einige Plattformen, z.B. RISC OS und AmigaOS, kommen ohne Umgebungsvariable aus.

Die Dateien der Library waren früher nicht immer beim Download dabei und konnten separat unter ACME_Lib2.zip heruntergeladen werden. Inzwischen ist die Library im Source-Download enthalten. Die Library-Dateien sind public domain.

Syntax-Highlighting[Bearbeiten | Quelltext bearbeiten]

Es gibt Ergänzungen für die Editoren Joe, Ultraedit, Visual Studio Code, Atom und gEdit und für eine LaTeX-Umgebung:

Cross-Compiling[Bearbeiten | Quelltext bearbeiten]

Windows
Linux und gedit

Schnelleinstieg[Bearbeiten | Quelltext bearbeiten]

Eine Quick-Referenz findet sich im Source-Code.

Beispiel mit Erklärung[Bearbeiten | Quelltext bearbeiten]

Ein kleines Beispiel, wie Programme unter ACME aussehen und wie sie übersetzt werden:

		!to "tiny.o", cbm	; Setzen der Ausgabedatei und des Formats
; Mit diesem Pseudo-Befehl wird der Dateiname und das Format festgelegt.
; Das kann auch über die Kommandozeilenoptionen "-o" und "-f" gemacht
; werden.

		*= $c000		; Setzen des Programmzählers
; Das geht auch mit der Kommandozeilenoption "--setpc".

		basout = $ffd2		; explizite, globale Label-Definition
; Damit ist "basout" als globales Label mit dem Wert $FFD2 definiert.

		; Eine Stringausgabeschleife:
		ldx #0
		beq +			; Schleifenstart
; '+' ist ein anonymes Vorwärtslabel. Andere sind "++", "+++", etc.
; Es kann wie ein jedes andere Label verwendet werden, aber verweist
; immer auf die nächste vorkommende Definition. Das erspart ein Ausdenken von Namen
; für unwichtige Label. Der Wert ist noch nicht gleich definiert und ACME setzt diesen
; erst beim zweiten Durchgang.

-		jsr basout		; Zeichen ausgeben
; '-' ist ein anonymes Rückwärtslabel. Andere sind "--", "---", etc.
; Es kann wie ein jedes andere Label verwendet werden, aber verweist
; immer auf die zuletzt vorkommende Definition. Das erspart ein Ausdenken von Namen
; für unwichtige Label. In dieser Zeile wird der Wert des Labels auf den des aktuellen
; Programmzählers gesetzt.

		inx			; erhöhe Zähler
+		lda .string,x		; hole Zeichen
; In dieser Zeile wird "+" auf den aktuellen Programmzähler gesetzt.
; ".string" ist ein lokales Label (weil es mit einem "." beginnt) und
; wird beim zweiten Durchgang von ACME ermittelt.

		bne -			; Prüfung, ob die Endekennung (=0) erreicht
; Hier ist die letzte Definition von "-" referenziert.

		rts
.string		!pet "Simples Beispiel", 13, 0
; Nun ist das Label ".string" auf den aktuellen Programmzähler gesetzt und
; alle Label sind definiert. Nach dem zweiten Durchgang von ACME wird die
; Binärdatei gespeichert. Der "!pet" Pseudo-Opcode speichert den String
; PetSCII-kodiert im Speicher als Byte-Werte. 

Die Datei sollte als "tiny.a" gespeichert werden und das Übersetzten geht dann mit:

acme tiny.a

ACME wird daraufhin die Datei einlesen und etwaige Fehler bei der Verarbeitung anzeigen. Falls kein Fehler auftritt, ist anschließend die Datei "tiny.o" vorhanden. Diese entspricht einer .prg-Datei und kann nach der Erstellung auf einem Emulator oder einem echten C64 laufen gelassen werden:

LOAD "tiny.o",8,1
SYS 49152


Pseudo-Opcodes[Bearbeiten | Quelltext bearbeiten]

Dateisteuerung[Bearbeiten | Quelltext bearbeiten]

  • !to
Aufruf !to DATEINAME, DATEIFORMAT
Zweck Definiert den Namen der Ausgabedatei und den dazugehörigen Typ.
Ohne Angabe wird die Quelldatei von ACME zwar vollständig verarbeitet, aber keine Ausgabedatei erzeugt.
Dies wäre nur für eine Syntaxüberprüfung und Fehlersuche nützlich.
Über die Kommandozeilenoptionen "--outfile" und "--format" kann man die Angaben ebenfalls machen, was eine Verwendung in Makefiles erleichtert.
Parameter DATEINAME: Eine Datei in "..."-Zeichen.
DATEIFORMAT: Name des Formats. Werte sind:
cbm mit Ladeadresse (Commodore-Format)
plain ohne Ladeadresse.
Fehlt das DATEIFORMAT, gibt ACME eine Warnung aus und
nimmt cbm an. (Überschreibbar mit "--format"):
Beispiele !to "eprom.p", plain ; don't add a load address
!to "demo.o", cbm ; add c64-style load address
  • !source !src
Aufruf !source DATEINAME
Zweck Assembliert einen anderen Quellcode aus einer separaten Datei. ACME macht danach im Text weiter.
Parameter DATEINAME: In der Schreibweise "..." wird es aus dem aktuellen Verzeichnis genommen
und mit <...> aus dem LIB-Verzeichnis.
Andere Schreibweise !src
Beispiele !source <6502/std.a> ; Read library file
!src "Macros.a" ; Read file from current dir
  • !binary !bin
Aufruf !binary DATEINAME[, [GRÖSSE] [, [SKIP]]]
Zweck Fügt eine Binärdatei direkt in die Ausgabedatei ein.
Parameter DATEINAME: Dateiangabe in ".." wird aus dem aktuellen Verzeichnis geladen mit
<...> aus dem LIB-Verzeichnis.
GRÖSSE: Ein Ausdruck, den der Parser versteht, aber beim ersten Durchlauf berechenbar sein muss.
Ist GRÖSSE angeben, wird nur bis zum Erreichen von GRÖSSE geladen.
Ist die Datei kleiner, wird der Rest entsprechend aufgefüllt.
SKIP: Offset, ab der die Daten aus der Datei geladen werden.
Andere Schreibweise !bin
Beispiele !binary <Own/menudata.b> ; insert library file
!bin "asc2pet.b", 256, 2 ; insert 256 bytes
; from file offset 2.
!bin "table", 2, 9 ; insert 2 bytes from offset 9
!bin "list",, 9 ; insert from offset 9 to EOF

Segmente[Bearbeiten | Quelltext bearbeiten]

  • *=
Aufruf *= EXPRESSION [, MODIFIER]
Zweck Setzt den Programmzähler zu einem Wert und startet eine neues Segment.

Der Wert muss einmal gesetzt werden (geht auch mit Hilfe der Option "--setpc" in der Kommandozeile). Wenn Segmente überlappen, wird eine Warnung ausgegeben.

Parameter EXPRESSION: Ein Ausdruck, den der Übersetzer versteht und der im ersten Durchgang berechnet werden kann.

MODIFIER: "invisible" und/oder "overlay". Mit diesen Schlüsselwörtern können die Überlappungs-Warnungen unterdrückt werden.

Beispiele
!to "TinyDemo", cbm	; define output file + format
*= $0801		; Start at C64 BASIC start
+basic_header		; Call program header macro
!src "main.a"		; include main program
*= $1000		; jump to new segment
!bin "music.b"		; load music to $1000
*= $8000		; jump to new segment
!bin "pic.b"		; load graphics to $8000
; After assembly, ACME will save everything from $0801
; up to the highest address written to. The resulting
; file will contain some big unused areas (zero'd),
; but demos will get compressed anyway... :)
  • !initmem
Aufruf !initmem EXPRESSION
Zweck Definiert "nicht geänderten" Speicher. ACME füllt den

Speicher mit diesem Wert für undefinierte Bereiche.
Sind Zwischenbereiche frei, werden diese so mit dem Wert gefüllt.

Parameter EXPRESSION: Ein im ersten Durchgang berechenbarer Wert.
Beispiele
!to "TinyDemo", cbm	; define output file + format
!initmem $ea		; Default memory content $ea.
*= $0801		; Start at C64 BASIC start
+basic_header		; Call macro to create program header
!src "main.a"		; include main program
*= $1000		; jump to new segment
!bin "music.b"		; load music to $1000
*= $8000		; jump to new segment
!bin "pic.b"		; load graphics to $8000
; This is the same example as before, but now the big
; unused areas will contain the value $ea instead of
; zero.


!initmem $ff	; Default memory content is now $ff.
; Useful if you want to store your code in an EPROM.

Werte einfügen[Bearbeiten | Quelltext bearbeiten]

  • !8 !by !byte
Aufruf !8 EXPRESSION [, EXPRESSION]*
Zweck Einfügen von 8-Bit-Werten
Parameter EXPRESSION: Jeder Ausdruck, den der Parser versteht.
Andere Schreibweise "!08", "!by", "!byte"
Beispiele !08 127, label, -128 ; Ausgabe einiger Werte
!by 14, $3d, %0110, &304, <*, "c"
!byte 3 - 4, label1 XOR label2, 2 ^ tz, (3+4)*7
  • !16 !wo !word
Aufruf !16 EXPRESSION [, EXPRESSION]*
Zweck Einfügen von 16-Bit-Werten
Parameter EXPRESSION: Jeder Ausdruck, den der Parser versteht.
Andere Schreibweise "!wo", "!word"
Beispiele !16 65535, label, -32768 ; Ausgabe einiger Werte
!wo 14, $4f35, %100101010010110, &36304, *, "c"
!word 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
  • !24
Aufruf !24 EXPRESSION [, EXPRESSION]*
Zweck Einfügen von 24-Bit-Werten
Parameter EXPRESSION: Jeder Ausdruck, den der Parser versteht.
Beispiele !24 16777215, label, -8388608, 14, $6a4f35
!24 %10010110100101010010110, &47336304, *, "c"
!24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
  • !32
Aufruf !32 EXPRESSION [, EXPRESSION]*
Zweck Einfügen von 32-Bit-Werten
Parameter EXPRESSION: Jeder Ausdruck, den der Parser versteht.
Beispiele !32 $7fffffff, label, -$80000000, 14, $46a4f35
!32 %1001011010010101001011010010, &4733630435, *, "c"
!32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2
  • !hex !h
Aufruf !hex HEX_ZIFFERNPAAR[ ][TAB][HEX_ZIFFERNPAAR]*
Zweck Einfügen von Bytewerten als Hex-Ziffern.
Dieser Pseudo-Opcode soll dazu anregen, externe Source-Code-Generator-Tools zu entwickeln.
Parameter HEX_ZIFFERNPAAR: Reine Hex-Ziffern ohne "0x"- oder "$"-Präfix. Leerzeichen und TABs sind als Trenner zwischen den Byte-Werten erlaubt.
Beispiele Richtig:
!h f0 f1 f2 f3 f4 f5 f6 f7 ; alle Werte einzeln getrennt
!h f0f1f2f3 f4f5f6f7 ; Werte gruppiert
!h f0f1f2f3f4f5f6f7 ; ganz ohne Gruppierung
Falsch:
!h f0f 1f 2f3 ; falsche Gruppierung
!h _LABEL ; Labels sind nicht erlaubt
  • !align
Aufruf !align UNDWERT, VERGLEICHSWERT [, FÜLLWERT]
Zweck Füllt den Speicher bis VERGLEICHSWERT erreicht ist. ACME
erzeugt FÜLLWERT bis der Programmzähler UND-verknüpft mit UNDWERT gleich dem VERGLEICHSWERT ist.
Parameter UNDWERT: Jeder Ausdruck, den der Parser verarbeitet, der aber auch schon beim ersten Durchgang berechenbar sein muss.
VERGLEICHSWERT: Jeder Ausdruck, den der Parser verarbeitet und bereits beim ersten Durchgang berechenbar sein muss.
FÜLLWERT: Jeder Ausdruck, den der Parser verarbeitet. Fehlt der Wert, wird der Default-Wert genommen (derzeit 234, das entspricht dem NOP-Befehl der 6502-CPU).
Beispiele ;Vermeidet den 6502-JMP()-Bug:
!align 1, 0 ; wartet auf gerade Adresse (Bit 0 = 0)

Label !word Pointer
; align code an einer Page-Grenze für eine
; Geschwindigkeitserhöhung beim Zugriff
!align 255, 0

  • !fill !fi
Aufruf !fill ANZAHL[, WERT]
Zweck Speicher mit einem Wert anfüllen
Parameter ANZAHL: Jeder Ausdruck, den der Parser versteht. Er muss beim ersten Durchgang berechenbar sein.

WERT: Jede Ausdruck, den der Parser versteht. Falls nicht gesetzt, wird der Defaultwert verwendet (derzeit 0).

Andere Schreibweise "!fi"
Beispiele !fi 256, $ff ; Reserviere 256 Bytes
!fill 2 ; Reserviere zwei Bytes
  • !skip
Aufruf !skip ANZAHL
Zweck Im Ausgabepuffer vorrücken, ohne ein neues Segment zu beginnen.
Parameter ANZAHL: Jeder Ausdruck, den der Parser verarbeitet und der bereits beim ersten Durchgang berechenbar ist. (Diese Beschränkung entfällt in einer zukünftigen Version.)
Beispiele !skip BUFSIZE ; BUFSIZE Bytes reservieren
!skip 5 ; 5 Bytes reservieren

Strings einfügen[Bearbeiten | Quelltext bearbeiten]

  • !convtab !ct
Aufruf !convtab KEYWORD [ { BLOCK } ]
oder !convtab DATEINAME[ { BLOCK } ]
Zweck Eine Textübersetzungstabelle.
Parameter KEYWORD: Name der Übersetzungstabelle:
pet Konvertierung zu PetSCII
raw keine Konvertierung.
scr konvertiert zu C64 Bildschirmzeichen.
DATEINAME: Name der Datei mit Konvertierungstabelle - Schreibweise "..." lädt aus dem aktuellen Verzeichnis, <...> aus dem Lib-Verzeichnis. Die Datei muss extakt aus 256 Zeichen bestehen.
BLOCK: Ein Assemblerblock, für den diese Übersetzungstabelle gilt. Der Defaultwert ist raw.
Andere Schreibweise "!ct"
Beispiele !convtab raw
!text "Test" ; gibt aus $54 $65 $73 $74
!ct pet
!tx "Test" ; gibt aus $d4 $45 $53 $54
!ct scr {
!tx "Test" ; gibt aus $54 $05 $13 $14
!ct "my_own_table_file"
!tx "äöüßÄÖÜ" ; wasauchimmer ... :)
}
!tx "Test" ; gibt erneut aus $d4 $45 $53 $54
Tipp: Die Erstellung einer Tabelle von ACME erledigen lassen:
!to "asc2pet.ct", plain ; no load address
*=0 ; pc = table index
; first create "as-is" table
!for i, 0, 255 {!byte i}
; now exchange upper and lower case characters
*=65, overlay
!for i, 1, 26 {!byte *+128}
*=97, overlay
!for i, 1, 26 {!byte *-32}
Diese Tabelle mittels convtab benutzt werden, um nach
PetSCII zu konvertieren (ok, ACME kann das eigentlich schon von selbst). :-)
  • !text !tx
Aufruf !text STRING_WERT[, STRING_WERT]*
Zweck Ausgabe eines Textes in der aktuellen Konvertierungstabelle.
Parameter STRING_WERT: Kann ein String in doppelten Anführungszeichen sein, oder ein Formelausdruck, den der Parser versteht.
Achtung: Ergebnisse von Berechnungen werden nicht konvertiert, Einzelzeichen schon.
Andere Schreibweise !tx
Beispiele !text "Loading...", Char_NewLine, "Filename:", 0
!tx "Offset character is ", offset-1+'a', 0
  • !pet
Aufruf !pet STRING_WERT[, STRING_WERT]*
Zweck Ausgabe eines Textes in der PetSCII Konvertierungstabelle (Klein-/Großbuchstaben des C64).
Parameter STRING_WERT: Kann ein String in doppelten Anführungszeichen sein, oder ein Ausdruck, den der Parser als Ausdruck versteht.
Achtung: Ergebnisse von Berechnungen werden nicht konvertiert, Einzelzeichen jedoch schon.
Beispiele !pet "Loading...", Char_NewLine, "Filename:", 0
!pet "Offset character is ", offset-1+'a', 0
  • !raw
Aufruf !raw STRING_WERT[, STRING_WERT]*
Zweck Ausgabe eines Textes ohne Konvertierung
Parameter STRING_WERT: Kann ein String in doppelten Anführungszeichen sein, oder ein Ausdruck, den der Parser als Ausdruck versteht.
Beispiele !raw "Loading...", Char_NewLine, "Filename:", 0
!raw "Offset character is ", offset-1+'a', 0
  • !scr
Aufruf !scr STRING_WERT[, STRING_WERT]*
Zweck Zum Darstellen von Text für C64 Bildschirm.
Parameter STRING_WERT: Kann ein String in doppelten Anführungszeichen sein, oder ein Ausdruck, den der Parser als Ausdruck versteht.
Achtung: Ergebnisse von Berechnungen werden nicht konvertiert, Einzelzeichen schon.
Beispiele !scr "Loading...", Char_NewLine, "Filename:", 0
!scr "Offset character is ", offset-1+'a', 0
  • !scrxor
Aufruf !scrxor XOR_WERT, STRING_WERT[, STRING_WERT]*
Zweck Benutzt die C64 Bildschirmkonvertierungstabelle und die XOR-Verknüpfung mit einem festen Wert (z.B. praktisch für die inverse Darstellung).
Parameter XOR_WERT: Jeder Ausdruck, den der Parser versteht.

STRING_WERT: Kann ein String in Anführungzeichen sein oder ein Ausdruck, den der Parser versteht.
Ergebnisse von Berechnungen werden nicht konvertiert und nicht XOR-verknüpft.
Einzelzeichen in Berechnungen werden konvertiert aber nicht XOR-verknüpft.

Beispiele !scrxor $80, "Loading..."
!scrxor $a0, "Offset char is ", (offset-1+'a') XOR $a0

Symbole (Labels)[Bearbeiten | Quelltext bearbeiten]

Sogenannte Labels sind Symbole, die eine Zeichenfolge darstellen, bestehend aus Buchstaben (a-z, A-Z), Ziffern, "_" (Underscore) und Zeichen mit Code >127, aber nicht mit einer Ziffer beginnen dürfen.

Sie beziehen sich auf unterschiedliche Dinge:

  1. globale Symbole (für Adressen oder Werte)
  2. lokale Symbole, deren Namen mit "." beginnen, beschränken sich auf eine Zone (siehe "!zone") oder eine Makrodefinition. Verwendet werden sie für Adressen, Variablen oder Parameter von Makros.
  3. lokale Symbole, deren Namen mit "@" beginnen, beschränken auf den Bereich zwischen der Verwendung des gleichnamigen globalen Symbols oder in einer Makrodefinitionen.
  4. lokale, namenlose Adresssymbole für kleine Schleifen oder das überspringen von kleinen Codesequenzen:
    • anonyme Symbole der Form '+', '++', '+++', ...
      beziehen sich auf die näherste vorausliegende Programmstelle, mit diesem Adress-Label.
    • anonyme Symbole der Form '-', '--', '---', ...
      beziehen sich auf die näherste zurückliegende Programmstelle, mit diesem Adress-Label.
  5. Spezielles Symbol '*', das der aktuellen Stelle entspricht, wo der Assembler gerade "Code" produziert.

Labels erhalten ihren Wert

  • als Adresse am Zeilenanfang vor einem Assembler- oder Pseudebefehl erkannt oder mit vorangestelltem "!addr" explizt in einer "="-Zuweisung als solche deklariert.
  • per einmaliger Zuweisung mit "="
  • in einer wiederholenden Zuweisung mit vorangestelltem "!set"
  • als übergebenen Parameter bei Makros.

Mit dem Voransetzen des Modifikationszeichens "~" bei einem Symbol in einer Makrodefinition, kann man innerhalb eines Makros per Referenz auf das als Makroparameter übergebene Label zugreifen. D.h. nichts anderes, dass im Makro auf das (üblicherweise) globale Label durchgeschrieben wird, also im Makro ein "lokaler" Aliasname zum übergebenen Label vorliegt. Damit kann man Rückgabewerte mit Makros realisieren.

Labels haben auch einen Typ, entweder ist es eine Adresse (kann mithilfe von Kommando !addr explizit als solches gesetzt werden) oder ein sonstiges Label.

  • !addr
Aufruf !addr LABEL = EXPRESSION
!addr { BLOCK }
Zweck Macht Labels mit neuem Wert gemäß Ausdruck EXPRESSION oder allen im angegeben Block BLOCK vorkommenden Zuweisungen zu solchen vom Typ "Adresse". Das kann dazu genutzt werden, um die Verwendung von Adress-Label in einem nicht passenden Kontext zu erkennen, was mit der Warnoption "-Wtype-mismatch" von ACME überprüft und gemeldet werden kann.
Parameter LABEL: Jeder gültige Labelname
EXPRESSION: Jeder Formelausdruck, den der Übersetzer akzeptiert.
Beispiele !addr BSOUT = $FFD2
  • !set
Aufruf !set LABEL = EXPRESSION
Zweck Weist einem Label einen neuen Wert gemäß Ausdruck EXPRESSION zu, auch wenn dieser bereits gesetzt ist. Dies wird dazu gebraucht, um etwa Schleifenzähler, Markierungsvariablen, "Flags" etc. im Verlauf der Assemblierung zu setzen und laufend zu verändern, wie z. B. für "!do".
Parameter LABEL: Jeder gültige Labelname
EXPRESSION: Jeder Formelausdruck, den der Übersetzer akzeptiert.
Beispiele Siehe "!do".
  • !zone
Aufruf !zone [TITLE] [ { BLOCK } ]
Zweck Wechselt zu einer neuen Zone mit eigenen, lokalen Symbolen. Zonen können verschachtelt oder auch hintereinander angeordnet sein.
Parameter TITEL: Kann aus Zeichen und Ziffern bestehen. Wird für nur Fehlermeldungen verwendet und meistens nicht angezeigt.

BLOCK: Ein Block von Assembleranweisungen. Falls kein Block vorhanden ist, wird die vorige Zone beendet und eine neue eröffnet. Wenn ein Block da ist, dann gilt die alte Zone danach weiter.

Andere Schreibweise !zn
Beispiele
.backgroundcolor = 0	; some local symbol
!zone File_IO		; new zone begins here
.backgroundcolor = 1	; so this is a different symbol
!zn LinkedList_Init
.backgroundcolor = 2
!zone LinkedList {	; start of nested zone
	; imagine some code here...
	!zone LinkedList_Init
	; imagine some more code here...
	!zone LinkedList_Body {
		; imagine yet some more code here...
		!zone LinkedList_SecondPart
		; imagine still some more code here...
	}
	!zone LinkedList_End
	; you know what to imagine here...
}
.backgroundcolor = 3	; => "Symbol already defined."
  • !sl
Aufruf !sl DATEINAME
Zweck Speichert die globalen Symbole in die gegebene Datei nach der Assemblierung. Diese Tabelle kann für eine weitere Assemblierung mit "!source" geladen werden.
Parameter DATEINAME: Eine Datei in "..." Anführungszeichen
Beispiele !sl "Symbols.a" ; produce symbol list after assembly

!sl "global" ; produce symbol list after assembly

Bedingte Assemblierung[Bearbeiten | Quelltext bearbeiten]

  • !if
Aufruf !if BEDINGUNG { BLOCK } [ else { BLOCK } ]
Zweck Bedingte Übersetzung. Falls die Bedingung wahr ist, dann wird der erste Block übersetzt, sonst der zweite, auf "else" folgende (sofern vorhanden). Seit Release 0.97 können per "else if" auch mehrere bedingte Blöcke direkt hintereinander angegeben werden, von denen natürlich maximal einer ausgeführt wird.
Parameter BEDINGUNG: Jeder Formelausdruck, den der Parser als Wert akzeptiert. Dieser muss bereits beim ersten Durchgang berechenbar sein.
BLOCK: Ein Block von Assembler-Statements.
Beispiele
!text "Black", 0        ; Choose wording according to
!if country = uk {        ; content of "country" label.
        !text "Grey"
} else {
        !text "Gray"
}
!byte 0
!text "White", 0


; Insert debug commands if label "debug" is not zero:
!if debug { lda #"z":jsr char_output }
  • !ifdef / !ifndef
Aufruf !ifdef LABEL { BLOCK } [ else { BLOCK } ]

!ifdef LABEL STATEMENT
!ifndef LABEL { BLOCK } [ else { BLOCK } ]
!ifndef LABEL STATEMENT

Zweck Bedingte Assemblierung, abhängig davon, ob ein Label gesetzt ist oder nicht. Wenn das Label definiert ist, wird der erste Statement-Block verarbeitet. Wenn das Label nicht definiert ist, dann wird der zweite Block gelesen (sofern vorhanden). Bei "!ifndef" ("if not defined") mit entsprechend umgekehrter Bedeutung.
Dieser Pseudobefehl ist besonders nützlich, um das Einlesen von Bibliotheksdateien effizient zu gestalten.

Sollte in eigenen Dateien nur dann benutzt werden, wenn man wirklich weiß, was man tut. - Falsch eingesetzt provoziert man damit leicht Fehlermeldungen.

Parameter LABEL: Jeder gültige Label-Name.
BLOCK: Ein Block von Assemblerbefehlen
STATEMENT: Jeder Assemblerausdruck.
Beispiele
; this was taken straight from <6502/std.a>:
!ifdef Lib_6502_std_a !eof	; parse this file once
Lib_6502_std_a = 1

Schleifen[Bearbeiten | Quelltext bearbeiten]

  • !for
aktueller Aufruf

(seit Version 0.94.12)

!for LABEL, START, END { BLOCK }
älterer Aufruf

(vor Version 0.94.12)

!for LABEL, END { BLOCK }
Zweck Schleifen in Assembler. Der Block der Assemblerbefehle wird mehrfach übersetzt, während LABEL von START bis ENDE gezählt wird. Flexiblere Schleifenstrukturen sind mit den Pseudo-Opcodes "!do" und "!while" möglich.

Die ältere Syntax beginnt die Zählung immer mit dem Wert Eins. Seit Version 0.94.12 erzeugt diese Syntax eine Warnung.

Parameter LABEL: Jeder valide Labelname. Startet mit dem Wert START und zählt dann bis END.
START: Jede Berechnung, die der Parser umsetzen kann, aber der Wert muss beim ersten Durchgang berechenbar sein.
END: Jede Berechnung, die der Parser umsetzen kann, allerdings muss der Wert beim ersten Durchlauf berechenbar sein.
BLOCK: Ein Block von Assemblerbefehlen.
Es ist nicht möglich, durch die im Block verwendeten Befehle, die Anzahl der Schleifendurchläufe zu ändern.
Beispiele
 ; conversion table: integer to BCD
 nt2BCD      !for Outer, 0, 9 {
                 !for Inner, 0, 9 {
                        !byte (Outer << 4) OR Inner
			}
		}
		!fill 156, $ff	; values above 99 give 255 (invalid)


		; conversion table: BCD to integer
	BCD2int	!for Outer, 0, 9 {
			!for Inner, 0, 9 {
				!byte 10 * Outer + Inner
			}
			!fill 6, $ff	; invalid BCD values give 255
		}
		!fill 96, $ff		; invalid BCD values give 255
  • !do
Aufruf !do [KEYWORD BEDINGUNG] { BLOCK } [KEYWORD BEDINGUNG]
Zweck Assemblerschleife: Der Block wird mehrfach übersetzt, in Abhängigkeit von einer oder mehreren Bedingungen. Die Bedingungen können am Anfang und/oder Ende des Blocks stehen und werden bei jedem Durchlauf ausgewertet. Laufvariablen oder sonstige sich änderende Variablen, die die Bedingungen und damit die Schleife beeinflussen, müssen mit "!set" entsprechend verändert werden.
Parameter KEYWORD: Angabe von "while" oder "until" (ohne Quotierung).
BEDINGUNG: Jede Formelausdruck, die der Übersetzer versteht, aber er muss bei jedem Durchlauf berechnet werden können.
BLOCK:Ein Block von Assembleranweisungen.
Beispiele
; eine Schleife mit Bedingung sowohl am Anfang als auch am Ende
!set a = 0			; setze Zähler
!do while loop_flag = TRUE {
	lda #a
	sta label+a
	!set a = a + 1
} until a > 6
; eine Schleife mit Bedingung am Anfang !do while * < $c000 { nop }
; eine Schleife mit Bedingung am Ende !do { !wo * + base } while * < base + 345
; eine Endlosschleife, die einen Fehler erzeugt !do while 3 < 4 { nop } until 3 = 4
; eine Leerschleife (ACME hängt sich auf) !do until 3 = 4 { } while 3 < 4
  • !while
Aufruf !while LAUFBEDINGUNG { BLOCK }
Zweck Assemblerschleife: Der Block wird so oft übersetzt, bis die Laufbedingung nicht mehr erfüllt ist.
Parameter LAUFBEDINGUNG: Jede Formelausdruck, die der Übersetzer versteht, aber er muss bei jedem Durchlauf berechnet werden können.
BLOCK:Ein Block von Assembleranweisungen.
Beispiele
!while * < $c000 { nop }

Sonstige Code-Steuerung[Bearbeiten | Quelltext bearbeiten]

  • !endoffile
Aufruf !endoffile
Zweck Stoppt das Übersetzen der aktuellen Quelldatei. So kann man den verbleibenden Rest der Quelldatei einfach übergehen.
Andere Schreibweise !eof
Beispiele
rts	; some assembler mnemonic
!eof
Though this text isn't preceded by a semicolon, it is
treated as if it were a comment. In fact, ACME doesn't
even parse this anymore - the file gets closed when
"!eof" is reached.
  • !warn
Aufruf !warn STRING_VALUE
Zweck Zeigt eine Warnung beim Übersetzen an.
Parameter STRING_VALUE: Ein String in Quotierungzeichen.
Beispiele
!if * > $a000 {
       !warn "Program reached ROM area."
}
  • !error
Aufruf !error STRING_VALUE
Zweck Erzeugt einen Fehler und es wird keine Datei erzeugt.
Parameter STRING_VALUE: Ein String unter Quotierungszeichen stehend.
Beispiele
rts	; end of some function
start	!source "colors.a"
end	!if end-start > 256 {
	!error "Color strings exceed 256 chars!"
}
  • !serious
Aufruf !serious STRING_VALUE
Zweck Erzeugt einen schwerwiegenden Fehler und bricht die Übersetzung ab.
Parameter STRING_VALUE: Ein String unter Quotierungszeichen stehend.
Beispiele
!source "part1.a"	; sets part1_version
!source "part2.a"	; sets part2_version
!if part1_version != part2_version {
      !serious "part1.a and part2.a don't match!"
}

Makros[Bearbeiten | Quelltext bearbeiten]

  • !macro
Aufruf !macro TITLE [[~]LABEL [, [~]LABEL]*] { BLOCK }
Zweck Definiert ein Makro, mit dem ein Code-Muster angelegt wird, das erst später bei Aufruf, eventuell auch parametrisiert, den entsprechenden Code generiert.
Parameter TITLE: Der Makroname (es gelten gleiche Regeln, wie für ein Label)

Ist das erste Zeichen ein ("."), gilt es nur lokal bezogen auf die jeweilige umgebende Zone (d.h. der Name kann ohne Gefahr einer Kollision mit globalen Makrodefinitionen verwendet werden).
LABEL: Der Name des Parameters beim Aufruf.
Normalerweise sollten die Namen lokal mit einem "." beginnen, damit verschiedene Aufrufe verschiedene Werte haben können.
Wenn das Label mit "~" beginnt, wird der Wert als Referenz und nicht als Wert übergeben. Eine Änderung (z. B. mittels "!set" ändert dann auch den globalen Label-Wert. Auf diese Art kann ein Makre Rückgabewerte liefern und verleiht einem Makro zu einem gewissen Grad das Verhalten einer Funktion.

Seit Version 0.86 können verschieden Makros den gleichen Namen haben, solange die Parameterliste eine unterschiedliche Argumentenanzahl aufweist oder deren Typ unterschiedlich ist (Call-By-Value bzw. Call-By-Reference). Daher können die folgenden Makros gleichzeitig verwendet werden, ohne dass sie kollidieren:

  • !macro process_bytes b1,b2 {...}
  • !macro process_bytes b1,b2,b3 {...}
  • !macro process_bytes b1,b2,~b3 {...}


Seit Version 0.97 kennt ACME auch Listen, damit kann einem Makro dann auch eine Parameterliste beliebiger Länge übergeben werden.
BLOCK: Block der Assemblerbefehle.

Beispiele
; far branch, as defined in <6502/std.a>                                   
!macro bne .target {
	beq * + 5
	jmp .target
}


; increase 16-bit counters                                                 
!macro dinc .target {
	inc .target
	bne +	; "bne * + 5" would not work in zp
	inc .target + 1
+
}

Anonyme Label-Referenzen dürfen auch in Makros verwendet werden (im Gegensatz zu manch anderem Assembler). Das liegt an der Implementierung der Makros, die sich bei ACME mehr an reale Funktionen anlehnt.

; load A and X                                                             
!macro ldax .target {
	lda .target
	ldx .target + 1
}


; store A and X                                                            
!macro stax .target {
	sta .target
	stx .target + 1
}


; use call-by-reference for return value                                   
!macro reserve ~.address, .amount {
	.address = external_pc
	!set external_pc = external_pc + .amount
}


; define a pixel row of a C64 hardware sprite                              
!macro SpriteLine .v {
	!by .v>>16, (.v>>8)&255, .v&255
}
  • +MACRONAME
Aufruf +MACRONAME [ARGUMENT [, ARGUMENT]*]
Zweck Aufruf eines Makros mit den passenden Argumenten.
Parameter MACRONAME: Der Name der bei der Definition vergeben wurde. Bei mehreren gleichnahmigen Makros wird jenes genommen, auf das das Parameterprofil passt.

ARGUMENT: Ein Wert oder Formel, die der Übersetzer verarbeitet.
Entsprechend der Definition - mit vorangestelltem "~" als Referenz (Call-By-Reference).

Beispiele
inc label
bne mark	; "near" branch
inc label2
+bne mark2	; "far" branch                                        


inc $fa		; increase  8-bit counter                             
+dinc $fb	; increase 16-bit counter


ldy label	; get byte                                            
+ldax label2	; get two bytes


; using macro calls in a macro definition                              
!macro cp16 .source, .target {
	+ldax .source
	+stax .target
}


; use call-by-reference for return value                               
!set external_pc = $0400
+reserve ~.line_buffer, 80
+reserve ~.in_buffer, 256
+reserve ~.out_buffer, 256
+reserve ~.byte_var, 1


; define a C64 hardware sprite                                         
;            765432107654321076543210
+SpriteLine %........................
+SpriteLine %.#......................
+SpriteLine %.##.....................
+SpriteLine %.###....................
+SpriteLine %.####...................
+SpriteLine %.#####..................
+SpriteLine %.######.................
+SpriteLine %.#######................
+SpriteLine %.########...............
+SpriteLine %.#########..............
+SpriteLine %.########...............
+SpriteLine %.######.................
+SpriteLine %.######.................
+SpriteLine %.##..##.................
+SpriteLine %.#....##................
+SpriteLine %......##................
+SpriteLine %.......##...............
+SpriteLine %.......##...............
+SpriteLine %........##..............
+SpriteLine %........##..............
+SpriteLine %........................
!byte 0	; pad to 64-byte block

Versetzte Assemblierung[Bearbeiten | Quelltext bearbeiten]

  • !pseudopc
Aufruf !pseudopc EXPRESSION [ { BLOCK } ]
Zweck Assembliert jenen Code, als wäre der Programmzähler (PC) auf den durch EXPRESSION vorgegeben Wert. Dieser Pseudo-PC-Wert gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block. Damit kann z.B. ein Code-Fragment erzeugt werden, das für einen anderen Adressbereich vorgesehen ist und erst zu einem späteren Zeitpunkt dorthin kopiert wird und erst dort lauffähig sein soll.

Mithilfe der Blocksyntax sind sogar Verschachtelungen möglich. Nach dem Ende des jeweiligen Blocks wird der zuvor aktive Pseudo-PC oder letztendlich der ursprüngliche PC wieder gültig.

Seit Version 0.97 existiert der "&"-Operator, mit dem man ein Symbol von seinem Wert innerhalb des PseudoPC-Blocks auf seinen Wert im umliegenden Block konvertieren kann.

Parameter EXPRESSION: Ein Ausdruck, der den neuen Pseudo-PC-Wert festlegt.

BLOCK: Ein Block von Assembleranweisungen.

Beispiele
*=$C000
casbuf = 828             ; Kassettenbuffer, für Code-Sequenz
tastbuf = $277           ; Tastaturpuffer
tbuffered = 198          ; Zeichen im Tastaturpuffer

install
    LDX #(routine_end-routine_start-1)
copyloop
    LDA routine_start,X
    STA casbuf,X
    DEX
    BPL copyloop
run
    JSR casbuf
    RTS

routine_start            ; Routine, die an anderer Stelle laufen soll
!pseudopc casbuf {
    LDX #0
.nextchar
    LDA .tcmd,X
    BEQ .leave           ; Endemarkierung
    STA tastbuf,X        ; Tastaturpuffer füllen
    INX
    BNE .nextchar
.leave
    STX tbuffered
    RTS
.tcmd
    !text ":run500",13,0 ; Kommando für den Tastaturpuffer
}
routine_end

Unterstützung für verschiedene CPUs[Bearbeiten | Quelltext bearbeiten]

  • !cpu
Aufruf !cpu TYP [ { BLOCK } ]
Zweck Wählt jenen CPU-Typ aus, dessen Instruktionssatz verstanden und für den der Code erzeugt wird. Gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block.

Vorgabe ist 6502 oder jene Angabe, die mit Parameter --cpu beim ACME-Aufruf gemacht wurde.

Parameter TYP: CPU-Typ als eines der folgenden Schlüsselwörter:
  • 6502 Familie der 6502
  • nmos6502 (alias "6510", Variante von 6502 inklusive der spezifischen illegalen Opcodes)
  • 65c02 Übermenge zu 6502, deckt Rockwell- und WDC-Varianten ab
  • r65c02 Übermenge zu 65c02, mit Rockwell-Erweiterungen
  • w65c02 Übermenge zu r65c02, mit WDC-Erweiterungen
  • 65816 Übermenge zu 65c02 für den 16-Bit-Ableger von WDC
  • c64dtv2 Übermenge zu 6510, erweitert um DTV2-Erweiterungen (BRA/SAC/SIR)
  • 65ce02 Übermenge zu r65c02
  • 4502 Übermenge zu 65ce02, verwendet im C65
  • m65 Übermenge zu 4502, verwendet im MEGA65

BLOCK: Ein Block von Assembleranweisungen.

Beispiele
!if cputype = $65c02 {                                          
    !cpu 65c02 {	; temporarily allow 65c02 stuff
        stz .todelete
    }
} else {
    pha
    lda #0
    sta .todelete
    pla
}
rts


!cpu 65816	; allow 65816 commands from here on            
  • !al
Aufruf !al [ { BLOCK } ]
Zweck Accumulator Long: Teilt dem Assembler mit, dass Akkumulator und Speicheroperationen 16-bittig sind und entsprechende Operanden im Code als 16-Bit-Werte auftreten. Gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block.
Parameter BLOCK: Ein Block von Assembleranweisungen.
Beispiele
 rep #$20
 !al
 LDA #1        ; takes 3 bytes (opcode + 16-bit immediate value, the accumulator is loaded with)!
  • !as
Aufruf !as [ { BLOCK } ]
Zweck Accumulator Short: Teilt dem Assembler mit, dass Akkumulator und Speicheroperationen 8-bittig sind und entsprechende Operanden im Code als 8-Bit-Werte auftreten. Gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block.
Parameter BLOCK: Ein Block von Assembleranweisungen.
Beispiele
 sep #$20
 !as
 LDA #1        ; takes 2 bytes (opcode + 8-bit immediate value, the accumulator is loaded with)!
  • !rl
Aufruf !rl [ { BLOCK } ]
Zweck Register Long: Teilt dem Assembler mit, dass Index-Register-Operationen 16-bittig sind und entsprechende Operanden im Code als 16-Bit-Werte auftreten. Gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block.
Parameter BLOCK: Ein Block von Assembleranweisungen.
Beispiele
 rep #$10
 !rl
 LDX #1        ; takes 3 bytes (opcode + 16-bit immediate value, register X is loaded with)!
  • !rs
Aufruf !rs [ { BLOCK } ]
Zweck Register Short: Teilt dem Assembler mit, dass Index-Register-Operationen 8-bittig sind und entsprechende Operanden im Code als 8-Bit-Werte auftreten. Gilt ab der aktuellen Stelle im Sourcecode oder für den folgenden Block.
Parameter BLOCK: Ein Block von Assembleranweisungen.
Beispiele
 sep #$10
 !rs
 LDX #1        ; takes 2 bytes (opcode + 8-bit immediate value, register X is loaded with)!

Ausdrücke, Operatoren und Funktionen[Bearbeiten | Quelltext bearbeiten]

Argumente bei Opcodes und Pseudo-Opcodes erlauben häufig einen Ausdruck ("EXPRESSION") der mit folgenden Operatoren[1] zusammengesetzt werden kann. Die Operanden werden dabei als 32-Bit-Ganzzahlen oder als Double-Precision-Fließkommazahlen behandelt.

Operatoren:

Priorität Syntax Bedeutung Alias
13 ! v Komplement NOT
12 v ^ w Potenzieren
11 - v Negation
10 v * w Multiplizieren
10 v / w Dividieren
10 v DIV w Integer-Division
(ganzzahlig)
10 v % w Divisionsrest (Modulo) MOD
9 v + w Addieren
9 v - w Subtrahieren
8 v << w Linksschieben ASL, LSL
8 v >> w arithmetisches Schieben nach rechts ASR
8 v >>> w logisches Schieben nach rechts LSR
7 < v niederwertiges Byte (Low Byte)
7 > v höherwertiges Byte (High Byte)
7 ^ v Bank-Byte einer Long-Adresse
6 v <= w kleiner oder gleich
6 v < w kleiner als
6 v >= w größer oder gleich
6 v > w größer als
5 v != w ungleich <>, ><
4 v = w gleich
3 v & w bit-weises UND AND
2 v XOR w bit-weises exklusiv ODER
1 w bit-weises ODER OR

Funktionen:

Funktion Bedeutung Ergebnistyp
int(x) in eine Ganzzahl wandeln Integer
float(x) in eine Fließkommazahl wandeln Float
sin(x) Sinus von x ermitteln Float
cos(x) Cosinus von x ermitteln Float
tan(x) Tangens von x ermittlen Float
arcsin(x) Arcussinus von x ermitteln Float
arccos(x) Arcuscosinus von x ermitteln Float
arctan(x) Arcustangens von x ermitteln Float

Kommandozeilen-Schalter[Bearbeiten | Quelltext bearbeiten]

  • -h, --help
    zeigt den eingebauten Hilfetext an und beendet das Programm.
  • -f, --format FORMAT
    setzt das Ausgabeformat, z.B. "-f cbm" für "mit Ladeadresse" oder "-f plain" für "ohne Ladeadresse"
  • -o, --outfile FILE
    legt die Ausgabedatei fest. Wird dieser Schalter benutzt, so wird der Pseudo Opcode "!to" ignoriert bzw. erzeugt eine Warnung.
  • -r, --report FILE
    schreibt ein Listing in die angegebene Datei, so dass man eine Übersicht hat, an welchen Adressen die Programmteile schließlich liegen.
  • -l, --symbollist FILE
    schreibt eine Liste aller globalen Symbole mit ihrem jeweiligen Zahlenwert in die angegebene Datei.
  • --labeldump FILE
    dies ist ein älterer Name für "--symbollist".
  • --vicelabels FILE
    wie "--symbollist", aber die Datei wird in einem Format erzeugt, das von VICE gelesen werden kann.
  • --setpc WERT
    setzt den Programmzähler. Alternativ künnte man am Anfang des Sourcecodes auch "*=WERT" schreiben.
  • --cpu CPU
    wählt den Pozessortyp. "6502" ist der Defaulttyp, andere Typen wie z.B. "65c02" oder "65816" stellen neue Instruktionen und/oder Adressierungsarten zur Verfügung. Um eine Liste aller unterstützten CPUs zu bekommen, muss man hier einfach nur irgend eine Grütze angeben. ;)
  • --initmem WERT
    setzt den Wert für "ungeänderten Speicher". Wird im Source ein Speicherbereich übersprungen, z.B. via "!skip" oder "*=neuer_Wert", so füllt ACME den Zwischenraum standardmäßig mit Null. Will man das Ergebnis auf ein EPROM brennen, kann man mit diesem Schalter den Wert auf 255 ändern.
  • --maxerrors ANZAHL
    Nach einer gewissen Anzahl angezeigter Fehlermeldungen bricht ACME den Assemblierversuch ab. Mit diesem Schalter kann man diese Zahl verändern.
  • --maxdepth ANZAHL
    setzt die maximale Rekursionstiefe für Datei-Includes und Makroaufrufe. Sollte tatsächlich jemand einen funktionierenden Sourcecode schreiben, der die voreingestellte Zahl überschreitet, kann hiermit das Limit beliebig erhöht werden.
  • --ignore-zeroes
    sorgt dafür, dass führende Nullen von Hex- oder Binärkonstanten nicht die Wahl der Adressierungsart beeinflussen. Standardmäßig sorgen führende Nullen dazu, dass z.B. "LDA $00fa" mit absoluter Adressierung assembliert wird, obwohl der reine Zahlenwert des Arguments ja auch Zeropage-Assemblierung ermöglicht. Wer das nicht möchte, kann diesen Schalter benutzen.
  • --strict-segments
    sorgt dafür, dass Segment-Überlappungen nicht als Warnungen, sondern als Fehler gemeldet werden.
  • -vZIFFER
    setzt die "Verbosity", d.h. die Redseligkeit. Je größer die Ziffer, desto mehr Text gibt ACME auf der Konsole aus.
  • -DSYMBOL=WERT
    setzt ein Symbol auf einen Wert. Mit "-Dsys=64" wird z.B. das Symbol "sys" auf den Wert 64 gesetzt, und im Source kann dann darauf reagiert werden (z.B. um das Programm an C64/C16/C128 anzupassen o.ä.).
  • -I PFAD/ZU/VERZEICHNIS
    fügt einen Datei-Suchpfad hinzu. Standardmäßig beziehen sich alle Dateiangaben im Sourcecode auf das Verzeichnis, in dem ACME gestartet wurde. Mit diesem Schalter kann auch in anderen Verzeichnissen gesucht werden.
  • -Wno-label-indent
    deaktiviert die Warnung, die von eingerückten Labels produziert wird.
  • -Wno-old-for
    deaktiviert die Warnung, die von der veralteten "!for"-Syntax produziert wird. Siehe auch weiter unten bei "--dialect".
  • -Wno-bin-len
    deaktiviert die Warnung, die von Binärkonstanten mit "seltsamer" Anzahl von Ziffern erzeugt wird. "Seltsam" bedeutet in diesem Fall "nicht durch vier teilbar".
  • -Wtype-mismatch
    aktiviert die Warnungen des Typensystems (selbiges funktioniert, jedoch fehlt dafür noch die offizielle Doku).
  • --use-stdout
    schreibt die Fehlermeldungen nicht zur Standard-Fehlerausgabe (file descriptor 2), sondern zur Standard-Ausgabe (file descriptor 1). Dieser Schalter wurde hinzugefügt, um Probleme mit integrierten Entwicklungsumgebungen beheben zu können.
  • --msvc
    ändert das Format der Fehlerausgaben so, dass MS Visual Studio damit umgehen kann.
  • --color
    benutzt ANSI-Farbcodes in den Fehlerausgaben.
  • --fullstop
    ändert das Startzeichen für Pseudo Opcodes von einem Ausrufezeichen zu einem Punkt. Dies erleichtert das Assemblieren von Sourcecodes, die eigentlich für andere Assembler geschrieben wurden. Wird dieser Schalter verwendet, so funktionieren natürlich die mit einem Punkt eingeleiteten lokalen Labels nicht mehr richtig, aber solche sollten in den fraglichen Sourcecodes ja eh nicht vorkommen.
  • --dialect VERSION
    sorgt dafür, dass ACME sich wie eine ältere Version verhält.
  • --test
    aktiviert experimentellen Code in ACME. Dieser Schalter sollte nur benutzt werden, wenn man an ACME mitentwickeln möchte.
  • -V, --version
    zeigt die verwendete Version von ACME an und beendet das Programm.

Siehe auch[Bearbeiten | Quelltext bearbeiten]

  • MCA2 ist eine Engine für Multiple Choice Adventures und verwendet ACME


Weblinks[Bearbeiten | Quelltext bearbeiten]

Referenzen[Bearbeiten | Quelltext bearbeiten]

  1. ACME Quick Reference (Operatoren) Sprache:englisch


Artikel des Monats.gif Dieser Artikel wurde Artikel des Monats.