HomeVDIGrundlagen des VDIAttributfunktionen

7.3 VDI-Bindings

Das VDIwird über ein einziges Unterprogramm aufgerufen, dem 5 Parameter übergeben werden; es handelt sich dabei um Adressen verschiedener Arrays, die zur Ein-/Ausgabe-Kommunikation benutzt werden. Um eine VDI-Funktion aufzurufen, muß der folgende Parameterblock mit den Adressen der unten beschriebenen Arrays bestückt werden:

typedef struct
{
   int16_t  *contrl;    /* Zeiger auf contrl-Array */
   int16_t  *intin;     /* Zeiger auf intin-Array  */
   int16_t  *ptsin;     /* Zeiger auf ptsin-Array  */
   int16_t  *intout;    /* Zeiger auf intout-Array */
   int16_t  *ptsout;    /* Zeiger auf ptsout-Array */
} VDIPB;

Die Adresse dieses Parameterblocks muß dann im Register d1 vermerkt, und zusätzlich Register d0.w mit dem Wert 0x73 (115) gefüllt werden. Durch einen TRAP#2 Systemaufruf kann dann das VDI direkt aufgerufen werden. Für den Pure-Assembler könnte das z.B. so aussehen:

        .EXPORT vdi         ; Funktion exportieren

        .IMPORT contrl      ; contrl-Feld importieren
        .IMPORT intin       ; intin-Feld  importieren
        .IMPORT ptsin       ; ptsin-Feld  importieren
        .IMPORT intout      ; intout-Feld importieren
        .IMPORT ptsout      ; ptsout-Feld importieren

        .DATA               ; Beginn des Daten-Segments

pblock: .DC.L contrl        ; Adresse des contrl-Arrays
        .DC.L intin         ; Adresse des intin-Arrays
        .DC.L ptsin         ; Adresse des ptsin-Arrays
        .DC.L intout        ; Adresse des intout-Arrays
        .DC.L ptsout        ; Adresse des ptsout-Arrays

        .CODE               ; Beginn des Code-Segments
vdi:     MOVE.L #pblock,D1  ; Adresse des Parameterblocks
         MOVE.W #$73,D0     ; Opcode des VDI
         TRAP   #2          ; GEM aufrufen
         RTS                ; raus hier

       .END                 ; Ende des Moduls

Darüber, welche Register verändert werden dürfen, gibt es keine klaren Informationen. Tatsache ist jedoch, daß die entsprechenden Routinen im ROM alle Register retten.

Im Gegensatz zum GEMDOS kennt das VDI leider keinen dokumentierten Rückgabewert für 'unbekannte Funktionsnummer'. Daher muss man sich im Zweifelsfall wie folgt behelfen:

Nun zu den einzelnen Arrays. Über jedes Feld können bestimmte Ein- bzw. Ausgaben getätigt werden; es gilt:

int16_t contrl[12] Über dieses Feld werden die Funktionsnummer, die Anzahl der Eingaben, die Kennung der Workstation sowie funktionsabhängige Parameter übergeben. Eingaben an das VDI werden dabei wie folgt eingetragen:
contrl[0] = Funktionsnummer
contrl[1] = Anzahl der Werte im ptsin-Array
contrl[3] = Anzahl der Werte im intin-Array
contrl[5] = Unterfunktionsnummer
contrl[6] = Kennung der Workstation
contrl[7..n] = abhängig von der Funktion


Ausgaben des VDI werden über die folgenden Felder gemacht:
contrl[2] = Anzahl der Werte im ptsout-Array
contrl[4] = Anzahl der Werte im intout-Array
contrl[6] = Kennung der Workstation
int16_t ptsin[1024]  
int16_t ptsout[256] Diese beiden Felder werden benutzt, um Paare von Koordinaten oder Maße in Pixeln (wie z.B. die Breite einer Linie, oder die Höhe eines Zeichens) zu übergeben. Die Größe dieser Felder hängt von der aufgerufenen Funktion ab.
int16_t intin[1024]  
int16_t intout[512] Diese Felder werden benötigt, um Werte wie den Index eines Zeichens oder einer Farbe zu übergeben. Die Größe dieser Felder hängt von der aufgerufenen Funktion ab.

Bei der Übergabe von Strings an das VDI sind einige Besonderheiten zu beachten: Diese werden grundsätzlich über die Felder intin und intout übergeben, wobei pro Zeichen ein Wort benutzt wird. Das hat den Vorteil, daß auch andere Codierungen als ASCII genutzt, und mehr als 256 Zeichen eines Zeichensatzes verwendet werden können.

Die Bindings arbeiten i.d.R. mit normalen C-Strings, und wandeln sie für das VDI um. Dabei wird die Länge des Strings in contrl[3] bzw. contrl[4] vermerkt, wobei kein abschließendes Null-Byte oder -wort vorhanden ist. Um z.B. eine in intout liegende Zeichenkette in einen C-String zu verwandeln, müssen contrl[4] Elemente kopiert (dabei die oberen 8 Bit abschneiden !) und anschließend ein Null-Byte angehängt werden.

Achtung: Wenn das Betriebssystem Threads unterstützt, muss unbedingt darauf geachtet werden, eine Multithread-sichere Bibliothek zu verwenden.

Querverweis: C-String nach VDI-String   VDI-String nach C-String   AES-Bindings

7.3.1 Wandel VDI-String nach C-String

VOID vdi_str_to_c( UWORD *src, UBYTE *des, int16_t len )
{
   while ( len > 0 )
   {
      *des++ = (UBYTE)*src++;  /* nur Low-Byte kopieren */
      len--;
   }
   *des++ = 0;  /* Ende des Strings */
}

7.3.2 Wandel C-String nach VDI-String

int16_t c_str_to_vdi( UBYTE *src, UWORD *des )
{
   int16_t  len;

   while (( *des++ = *src++ ) != 0 )
      len++;
   return (len); /* Stringlänge ohne Null-Byte */
}

HomeVDIGrundlagen des VDIAttributfunktionen