Pirates!/DSL

Aus C64-Wiki
Zur Navigation springenZur Suche springen

<< zurück zu Pirates!

Pirates! benutzt intern eine einfache Stack-basierte domänenspezifische Sprache (DSL), deren Bytecode auf Diskette in Dateien mit der Erweiterung SID vorliegt und der von einem in Assembler geschriebenen Interpreter abgearbeitet wird.

Integration[Bearbeiten | Quelltext bearbeiten]

  • $9F00-$9FFF: 16-Bit-Variablen
  • $A300-$BFFF: SID-Interpreter und -Programm

SID-Routinen werden von BASIC aus via Programmzeile 12900 geladen und via 5950 ausgeführt. SID-Variablen werden bei Zeile 7 geschrieben und bei 9 gelesen.

Opcodes[Bearbeiten | Quelltext bearbeiten]

Variablenoperationen[Bearbeiten | Quelltext bearbeiten]

PUSH_VAR (128-191)
Legt den Inhalt einer Variable auf den Stack. Der Opcode-Wert minus 128 ergibt die Variablennummer.
POP_VAR (192-255)
Holt einen Wert vom Stack und speichert ihn in eine Variable. Der Opcode-Wert minus 192 ergibt die Variablennummer.

Stack-Operationen[Bearbeiten | Quelltext bearbeiten]

POP (43)
Entfernt das oberste Element vom Stack.
SWAP (14)
Tauscht die beiden obersten Elemente auf dem Stack.
DUP (17)
Dupliziert das oberste Element auf dem Stack.
WORD (15)
Wandelt den obersten Wert auf dem Stack in ein 16-Bit-Word um und schreibt es auf den Stack. (Vorzeichenexpansion?)
WORD_CONST (80)
Legt das auf den Opcode folgende Byte als 16-Bit-Wert auf den Stack.
PUSH_BYTE (82)
Legt das auf den Opcode folgende Byte auf den Stack. (Vorzeichenexpansion?)
PUSH_WORD (81)
Legt die beiden auf den Opcode folgenden Bytes (erst Hi, dann Lo) als Word auf den Stack.

Arithmetische Operationen[Bearbeiten | Quelltext bearbeiten]

NEG (2)
Negiert den obersten Wert auf dem Stack.
INC (5)
Inkrementiert den obersten Wert auf dem Stack.
DEC (6)
Dekrementiert den obersten Wert auf dem Stack.
ADD (32)
Addiert die beiden obersten Werte auf dem Stack und legt das Ergebnis auf den Stack.
SUB (33)
Subtrahiert den zweitobersten Wert vom obersten Wert auf dem Stack und legt das Ergebnis auf den Stack.
MUL (34)
Multipliziert die beiden obersten Werte auf dem Stack und legt das Ergebnis auf den Stack.
DIV (35)
Dividiert den zweitobersten Wert durch den obersten Wert auf dem Stack und legt das Ergebnis auf den Stack.
SHR (65, 76)
Rechtsverschiebung (Division durch Potenz von 2) des obersten Werts auf dem Stack um den auf den Opcode folgenden Wert (Byte).
SHL (66)
Linksverschiebung (Multiplikation mit Potenz von 2) des obersten Werts auf dem Stack um den auf den Opcode folgenden Wert (Byte).
ADD_CONST (78)
Addiert eine Konstante (das auf den Opcode folgende Byte) zum obersten Wert auf dem Stack.

Bitweise Operationen[Bearbeiten | Quelltext bearbeiten]

AND_255 (7)
Führt eine bitweise UND-Operation mit 255 mit dem obersten Stack-Element durch.
AND (42)
Führt eine bitweise UND-Operation zwischen den beiden obersten Werten auf dem Stack durch und legt das Ergebnis auf den Stack.
AND_CONST (72)
Führt eine bitweise UND-Operation mit einer Konstanten (auf den Opcode folgendes Byte) durch und legt das Ergebnis auf den Stack.
OR_CONST (73)
Führt eine bitweise ODER-Operation mit einer Konstanten (auf den Opcode folgendes Byte) durch und legt das Ergebnis auf den Stack.
EOR_CONST (74)
Führt eine bitweise Exklusiv-ODER-Operation mit einer Konstanten (auf den Opcode folgendes Byte) durch und legt das Ergebnis auf den Stack.

Mathematische Funktionen[Bearbeiten | Quelltext bearbeiten]

RND (8)
Generiert eine Zufallszahl (Bereich vom Stack) und legt das Ergebnis auf den Stack.
ABS (9)
Berechnet den Absolutwert des obersten Stack-Elements und legt das Ergebnis auf den Stack.
SGN (10)
Berechnet das Vorzeichen des obersten Stack-Elements und legt das Ergebnis auf den Stack.
SIN (40)
Berechnet den Sinus (die obersten beiden Stack-Elemente sind Parameter) und legt das Ergebnis auf den Stack.
COS (41)
Berechnet den Kosinus (die obersten beiden Stack-Elemente sind Parameter) und legt das Ergebnis auf den Stack.
ATAN (47)
Berechnet den Arkustangens (die obersten beiden Stack-Elemente sind Parameter) und legt das Ergebnis auf den Stack.

Speicheroperationen[Bearbeiten | Quelltext bearbeiten]

PEEK (11)
Liest ein Bytes aus der obersten auf dem Stack liegenden Adresse und schreibt es auf den Stack.
DPEEK (13)
Liest einen 16-Bit-Wert aus der obersten auf dem Stack liegenden Adresse und schreibt es auf den Stack.
PEEK_OFFSET (67)
Liest ein Byte aus der obersten auf dem Stack liegenden Speicheradresse (plus 8-Bit-Offset, das auf den Opcode folgt) und schreibt es auf den Stack.
POKE (48, 52)
Holt eine Speicheradresse und ein Byte vom Stack und schreibt das Byte an die Adresse.

Kontrollfluss[Bearbeiten | Quelltext bearbeiten]

BREAK (0)
Unterbricht die Ausführung.
IF_GT_0 (37)
Ausführung weiterführen, falls der oberste Wert auf dem Stack größer als 0 ist (ansonsten zum ELSE/ENDIF/ENDALLIF).
IF_EQ_0 (38)
Ausführung weiterführen, falls der oberste Wert auf dem Stack gleich 0 ist (ansonsten zum ELSE/ENDIF/ENDALLIF).
IF_NEQ (56)
Ausführung weiterführen, falls die beiden obersten Werte auf dem Stack ungleich sind (ansonsten zum ELSE/ENDIF/ENDALLIF).
IF_NEQ_0 (97)
Ausführung weiterführen, falls der oberste Wert auf dem Stack ungleich 0 ist (ansonsten zum ELSE/ENDIF/ENDALLIF).
IF_CMP (113)
Vergleicht die beiden obersten Werte auf dem Stack mittels des auf den Opcode folgenden Komparators (0: "==", 1: ">", 255: "<").
ELSE (123)
Beginnt einen ELSE-Block.
ENDIF (125)
Beendet einen IF-Block.
ENDALLIF (124)
Beendet alle IF-Blöcke.
LABEL (79)
Definiert ein Label (Byte-Wert folgt auf Opcode).
GOTO (75)
Springt zu einem Label (Byte-Wert folgt auf Opcode).
FOR (112)
Beginnt eine FOR-Schleife. Startwert und Endwert kommen vom Stack, Variablennummer folgt auf Opcode.
NEXT (64)
Beendet die FOR-Schleife der Variable, deren Nummer auf den Opcode folgt.
RESTART (127)
Startet das Programm neu.

Funktionsaufrufe[Bearbeiten | Quelltext bearbeiten]

FUN (68)
Definiert (???) bzw. ruft Funktion mit der auf den Opcode folgenden Nummer (Byte) auf.
RETURN (1)
Kehrt aus einer Funktion zurück.

Ein-/Ausgabe[Bearbeiten | Quelltext bearbeiten]

PRINT (98)
Gibt den obersten Wert des Stacks mit der auf den Opcode folgenden Formatierung (Byte) aus.
SYS (99)
Ruft Routine an der obersten auf dem Stack liegenden Adresse auf (Parameter in auf Opcode folgendem Byte).
LOAD (44)
Lädt Daten (nutzt obersten Wert vom Stack).
SAVE (45)
Speichert Daten (nutzt obersten Wert vom Stack).

Spezielle Funktionen[Bearbeiten | Quelltext bearbeiten]

FIRE (4)
Liest Joystick mit der auf dem Stack liegenden Nummer aus und legt den Zustand seines Feuerknopfs auf den Stack.
JOYSTICK (16)
Liest Joystick mit der auf dem Stack liegenden Nummer aus und schreibt Y- und X-Auslenkung auf den Stack.
CRSR_Y (70)
Setzt die Y-Position des Cursors auf den auf den Opcode folgenden Wert (Byte).
CRSR_X (71)
Setzt die X-Position des Cursors auf den auf den Opcode folgenden Wert (Byte).
SPRITE_Y (102)
Setzt die Y-Position des Sprites mit der auf den Opcode folgenden Nummer (Byte) auf den obersten Wert des Stacks.
SPRITE_X (103)
Setzt die X-Position eines Sprites mit der auf den Opcode folgenden Nummer (Byte) auf den obersten Wert des Stacks.
CLAMP (53)
Stellt sicher, dass ein Wert innerhalb eines Bereichs liegt (obere Grenze liegt oben auf dem Stack, dann untere, dann der Wert) und legt das Ergebnis auf den Stack.
ENSURE_JUMP (114)
Stellt sicher, dass ein Wert innerhalb eines Bereichs liegt, springt sonst zu auf Opcode folgenden Label (?).

Unbekannter Opcode[Bearbeiten | Quelltext bearbeiten]

UNKNOWN_77 (77)
Unbekannter Opcode (mit auf Opcode folgenden Byte-Parameter), der auf $9FE1 zugreift.