Variablen:

Register der Maschine:
BP : Basepointer     :Zeiger auf Basis der localen Variablen
GP : Globalpointer   :Zeiger auf Basis der globalen Variablen
PC : Programcounter  :Zeiger auf aktuelles Befehlsbyte
SP : Stackpointer    :Zeiger auf Stack fr Expressions/Weitere Unterroutinen

Alle Variablen haben den Typ: LONG
Sie unterscheiden sich nur in ihrer Verwendung (COMPILER!)
Folgende Typen:
LONG = Standardvariable zum Speichern von userdefinierten und freien Zahlen
BOOL = 0=FALSE / Alles andere=TRUE
STRING = Zeiger ins Stringfeld - auch bei Stringconstanten!
         Achtung: Bei Write-zugriff auf String (nur funktion: inputstring
         ist die Laenge zu berpruefen!)
CHARID = Ein Character 0-63 (auch Monster)
OBJECTID = Ein Object 0-255
MONSTERID = Ein Monster 0-255
OBJECTTYPE = Ein Typ 0-7 : NOTHING,WAFFE,BOGEN....  etc.
DISTANCE = Ein Distance auf 0-6
ABILITY = Eine Ability 0-7 aus KEINE,DEAD,PSND.... etc.

Der Compiler hat zu berpruefen ob die Anzahl der bergabeparameter,
und ob der Typ der Variablen stimmt!

-------------------------------------------------------------------------
Bei Angabe von Assemblerbefehlen mit Paramter bedeutet dies das der/die
Paramter von links nach rechts vorher gePUSHed werden muessen.

-------------------------------------------------------------------------
Aufruf einer Unterroutine:

1.Durchlaufen der Anweisungen die die bergabeparameter auf dem Stack
  ablegen.
2.Aufruf der Unterroutine
  -Rcksprungadresse und BP werden auf dem Stack abgelegt und neuer
   BP liegt ab SP
   Programm: JSR Routine
  -Reservierung localer Variablen
   Programm: RES Anzahl;
    *Auf die bergabevariablen kann mit negativem Offset ab -12 abwaerts
    *zugegriffen werden -12(BP),-16(BP)....
    *Programm: PUSH -10; RLV ;
    *Die localen Variablen befinden sich bei 0(BP),4(BP)....
3.Beenden der Unterroutine
  -Die Rckgabeparameter werden auf dem Stack abgelegt
   Programm: PUSH Offset; RLV;
  -Anzahl der Rckgabeparameter ablegen
   Programm: Push Anzahl_return
  -Anzahl der aufrufenden Parameter ablegen (zwecks Stack aufraeumen)
   Programm: Push Anzahl_call
  -Return-Befehl
   Programm: RET

Bei globalen Variablen muss kein Basepointer addiert werden, da die erste
bei Adresse 0 liegt.

Fr die Initialisierung des Stacks steht am Anfang des Programmoffset-blocks
ein Langwort das den bentigten Global-Stack und eines das den
voraussichtlichen Gesammtstack angibt.

Aufruf einer Prozedur genauso, nur Anzahl der Rckgabeparameter 0
---------------------------------------------------------------------------
Der If-Then-Else Befehl:

1.Bedingung auf dem Stack legen
  Programm z.B.:
                         E Wert1,Wert2
2.Programm:              JCC TrueZweig
            FalseZweig:  .....
                         JMP Ende
            TrueZweig:   .....
            Ende:        .....
---------------------------------------------------------------------------
Der While Befehl:

Programm: while:            JMP while_cond
          while_loop:       ....
          while_cond:       N Wert1,Wert2     <- Bedingung invertieren
                            JCC while_loop
---------------------------------------------------------------------------
Der Case Befehl:

Wiederholtes If-Then-Else (mit weiterem If-Then... im FalseZweig)
---------------------------------------------------------------------------
Wertzuweisung:

global:
PUSH Wert
ASS Variable

local:
PUSH Wert
ALV Offset
---------------------------------------------------------------------------


Tokens:

$00 ADD addition
$01 SUB subtract
$02 MUL multiply
$03 DIV divide
$04 ASL shift left   | mit             ---|
$05 ASR shift right  | vorzeichen         | ist dasselbe!
$06 LSL    | ohne                      ---|
$07 LSR    | vorzeichen
$08 E   is equal?
$09 LE  is less equal?
$0a L   is less?
$0b GE  is greater equal?
$0c G   is greater?
$0d NE  is not equal?
$0e AND
$0f OR
$10 XOR
$11 NOT
$12 PUSHB Push Constant Byte (as long)
$13 PUSHW Push Constant Word (as long)
$14 PUSHL Push Constant Long
$15 POP
$16 DUP duplicate (sth on stack)
$17 SWAP vertausche elemente auf stack
$18 JC   jump conditional (wenn true)
$19 JMP  jump
$1a JSR  jump suppenroutine
$1b EXT  calls internal funktion (oder auch direkt...)
$1c RET  return from subroutine (mit anzahl der rckgabewerte)
$1d REF  holt wert einer Variablen
$1e ASS  holt adresse und wert, schreibt wert in adresse
$1f PBP  Push Basepointer
$20 RES  Reserviert Platz fr locale Variablen
$21 RLV  Wert einer localen Variable auf Stack ablegen
$22 ALV  Zuweisung an eine locale Variable
Was zu tun mit Stringconstanten?

Genaue Funktionsweise der Befehle:

Values sind grundstzlich.l !

$00-$11: **
     Get Value1 from Stack
     Get Value2 from Stack
     Value=Value1 Operand Value2
     Push Value on Stack
       Bei Vergleichen: Value=0: Value1 Operand Value2 = True
                        Value=1: Value1 Operand Value2 = False
PUSH: Value
     Push Value on Stack
POP: **
     Get Value from Stack
DUP: **
     Get Value from Stack
     Push Value on Stack
     Push Value on Stack
SWAP: **
     Get Offset from Stack
     Read Value1 from Offset(Stack)
     Get Value2 from Stack
     Push Value on Stack
     Store Value2 to Offset(Stack)
JC: **
     Get Offset from Stack
     Get Value from Stack
     If Value=0 then PC=PC+Offset
JMP: **
     Get Offset from Stack
     PC=PC+Offset
JSR: **
     Get Offset from Stack
     Push PC on Stack
     PC=PC+Offset
     Push BP on Stack
     BP=SP
EXT: **
     Get Funktionnumber from Stack
     Special (call funktion etc.)
RET: **
     Get Number_of_calling_Values from Stack
     Get Number_of_return_Values from Stack
     Get all Values from Stack
     Get BP from Stack
     Get PC from Stack
     SP=SP-Number_of_calling_values
     Push all Values on Stack
REF: **
     Get Adress from Stack
     Push Value of Variable on Stack
ASS: **
     Get Adress from Stack
     Get Value from Stack
     Store Value in Variable
PBP: **
     Push Basepointer on Stack
RES: **
     Get Number_of_Bytes
     SP=SP+Number_of_Bytes
RLV: **
     Get offset from Stack
     offset=offset+BP   (add #BP,-4(SP))
     Push offset
     REF
ALV: **
     Get offset from Stack
     offset=offset+BP
     push offset
     ASS

-------------------------------------------------------------------------
Predefined Functions:

-Check if somebody owns an object
 BOOL=CheckPocket(CharID,Object)
-Check if last combat was won/lost/runaway/negociate
 BOOL=Combat(WON|LOST|RUN|NEGO) : LOST ist fr RUN und NEGO auch gesetzt
-Check how many days have passed
 DaysPassed=Days()
-Check the time of day
 TimeOfDay=TOD()
-Check the levels of characters
 Level=CharLevel(CharID)
-Check if payroutine was successful
 BOOL=Pay(Amount) => Payroutine gibts als BOOL gleich zurueck
-Get a Random number
 BOOL=Percent(Prozentsatz) => ist True fr Zufallszahl 0-100 < Prozensatz
-Get a Key (with and without wait)
 Char=GetKey()
 Char=WaitKey()
-Check for the Standardkeys (examine character)
 BOOL=ExamineKeys(Char) : Fhrt Examineroutine bei x,1,2,3,4,5 aus
-Print a String
 Print(String)
-Print a Title
 PrintTitle(String)
-Show a Picture
 Picture(Picture)
-Get X and Y Coords of Party
 Coord,Coord=GetXY()
-Store x and y Coords of Party
 StoreXY(Coord,Coord)
-Move Party
 Move(XRelative,YRelative)
-Get View-Direction of Party
 View=GetView()
-Store View-Direction of Party
 StoreView(View)
-Turn Party
 Turn(Turns)
-Set Dungeon
 Dungeon(DungeonNumber)
-Define Attack
 Attack()
 Attack(Groups,MonsterID,Amount,MonsterID,Amount......) Variable Anzahl
-Clear Screen
 ClearScreen()
-Set Event to X,Y
 SetEvent(Event,Coord,Coord) Event=0 => ClearEvent
    ...armer Compiler: SetEvent(Event,GetXY()) mglich, das GetXY 2 Rckgabewerte
-Call routines like: QUIT,STAY,BUY,SELL,HEAL,LEARN,Advance,Recover,Train,AdvanceClass
 QUIT(),STAY() etc.
-Input of a String
 Input(String)
-Set/Clear Ability Flag: Poison.....
 BOOL=GetAbility(CharID,Ability) True wenn z.b. poisoned
 SetAbility(CharID,Ability)
 ClearAbility(CharID,Ability)
-Get/Store Hitpoints, auch SP
 GetHP(CharID)
 SetHP(CharID)
-Get/Store MaxHP, auch SP
 GetMaxHP(CharID)
 SetMaxHP(CharID)
-Give/Take Object
 DeleteObject(CharID,ObjectID)
 OfferObject(ObjectID)
-Set/Clear Door/Wall/SecretDoor
 Set(Door|Wall|SecretDoor,North|East|South|West)
-Execute a Spell
 Spell(CharID1,CharID2) , also ganz normaler Funktionsaufruf

Vordefinierte Constanten:
Wall = 0
Door = 1
SecretDoor = 2
North = 0
East = 1
South = 2
West = 3
WON = 0
LOST = 1
RUN = 2
NEGO = 3

-------------------------------------------------------------------------

Grammatik: (Spaces und CR sind an mehr als angegebenen Stellen moeglich
==========  => "C")

Name und CR werden als klar vorausgesetzt

Programmstruktur ::= { <Funktion> | <Procedur> }1,ue

Procedur ::= <Name>"(" <Variablenliste> ")" ;<CR>
             <Programm> <CR>

Funktion ::= <Name>"(" <Variablenliste> ")" ;<CR>
             "{" { <Programmzeile> }0,ue
             <Rckgabe> "}" <CR>

Programm ::= "{" { <Programmzeile> }0,ue "}"

Programmzeile ::= <Befehl> <CR>

Befehl ::= ( <IF-Befehl> |
             <CASE-Befehl> |
             <WHILE-Befehl> |
             <Zuweisung> |
             <Unterroutinenaufruf> )

IF-Befehl ::= IF <Vergleich> "{" <Programm> "}"
              { ELSE "{" <Programm> }0,1 "}"

CASE-Befehl ::= CASE { <Vergleich> ":" <Programm> }1,ue

WHILE-Befehl ::= WHILE <Vergleich> <Programm>

Rckgabe ::= RETURN <Variable>

Vergleich ::= ( <Variable> { <Vergleichsoperator> <Variable> }0,1 )

Variable ::= <Typ> { <Operator> <Typ> }0,ue

Type ::= ( <Name> | <Constant> | <Funktionsaufruf> )

Vergleichsoperator ::= ( "=" | "<" | ">" | "<=" | ">=" | "<>" )

Constant ::= ( <Zahl> | <String> )

String ::= """<Name>"""

Unteroutinenaufruf ::= CALL <Name>

Zuweisung ::=  <Variable> = <Variable>

Operator ::= ( "+" | "-" | "*" | "/" )

<Funktionsaufruf> ::= <Name> "(" <Variablenliste> ")"

<Variablenliste> ::= <Variable> { "," <Variable> }0,ue


SPELLS:
=======

Spells werden als Proceduren mit den bergabeparamtern:
SPELL(CHARID,CHARID), wobei das erste der Angreifer, das zweite
der Angeriffene ist, realisiert.

Stack:
======

global Variables        <- Globalpointer
$0000                   leerinitialisierung fr
$0000                   letzen Rcksprung
local Variables         <- Localpointer (Basepointer)
<Stack fr Expressions> <- Stackpointer
..... bei Aufruf einer unterroutine: ....
Alter Basepointer
Rcksprungadresse
local Variables
<Stack fr Expressions>
.... etc. ....



