mec0

 

MagicPC :mec0-Scnittstelle (MPS)

Im Wesentlichen ist das folgende eine Aufarbeitung der Originaldokumentation von ASH Mit und mit werde ich sie noch durch eigene Erleuterungen und Beispiele ergänzen.

        FS 15.08.96

 Programmierschnittstelle für MagiC_PC

(MPS = Magic_Programmier_Schnittstelle)



0. Allgemeines

Dateien des Demobeispieles:



Um eigene MPS_DLLs zu entwickeln, verwenden Sie bitte
mps_base.def, mps_base.h und mps_base.cpp unverändert. Zu ändern/ergänzen sind mps_demo.h und mps_demo.cpp
Insbesondere wählen Sie bitte eine eigene DLL_ID in
mps_demo.h zur Unterscheidung von anderen MPS_DLLs.

I. Konzept

Windowsseitig können über dynamische Bibliotheken (DLLs) beliebig viele Funktionen (im folgenden MPS_Funktionen genannt) eingerichtet werden, die innerhalb von MagiC_PC (motorolaseitig) aufgerufen werden können.

In der Startphase versucht MagiC_PC, alle DLLs im  Unterverzeichnis MPS zu laden und zu starten. Dazu ruft MagiC_PC drei von der DLL zu exportierende Funktionen auf (in dieser Reihenfolge):

  1. mps_get_type():  muß 0x4701 liefern!
  2. mps_get_functionlist(...): ermittelt DLL_ID und MPS_Funktionsliste der DLL.
  3. mps_magicinfo: teilt MagiC_PC-eigene Daten/Funktionen mit, die die DLL bei Bedarf verwenden kann.

Alle in 2) angemeldeten Funktionen können über spezielle Opcodes motorola-seitig
aufgerufen werden. Näheres zum Aufruf siehe
IV.

II. Zu exportierende Funktionen der DLL ("Basisfunktionen")

Eine MPS-DLL muß genau 3 C-Funktionen unter fester Ordinalzahl exportieren:
(auch Basisfunktionen genannt)
(siehe
mfp_base.def, mfp_base.cpp, mfp_base.h )

  1. @101: int mps_get_type()
       ----------------------
      Zweck: Dient der Rückversicherung, ob tatsächlich MPS_DLL erwischt.   !! Rückgabewert: 0x4701 !!
  2. @102: int mps_get_functionlist(DWORD *mps_dll_id,MPS_fuptr **p_funktionsliste);
       ------------------------------
    Zweck: MagiC_PC möchte DLL_ID und MPS_Funktionsliste wissen.
    Rückgabewerte:
       *mps_ddl_id:        DLL_ID (4 Bytes, DLL_spezifisch zu wählen!!)
       *p_funktionsliste:  Zeiger auf Liste der MPS_Funktionen.
       return: 1: alles klar
  3. @103: void mps_magicinfo(MPS_magicinfo *is);  
       ------------------------
    Zweck: MagiC_PC teilt eigene Infos / Funktionspointer mit, die die DLL   verwenden darf:
       typedef struct {
     DWORD sizeof_str;  // Größe von MPS_magicinfo
     DWORD magic_version;  // z.B. 0x010001
     DWORD magic_date;  // z.B. 19960815  (aufsteigend)
     BYTE  is_demo;   // Ist demoversion?
     BYTE  uu1, uu2, uu3;  // noch unbenutzt, 0

     BYTE *(*intel_adr)(DWORD motadr); // Adressumrechnung Motorola -> Intel
     BYTE  *(*intel_ptr)(DWORD motptr); // Pointer-Umrechnung Motorola -> Intel (NULL bleibt NULL!)

     WORD (*swap_word)(WORD w); // Ein Word swappen
     DWORD (*swap_long)(DWORD dw); // Ein Langwort swappen
     } MPS_magicinfo;
       Die Adressumrechnungen ergeben NULL, falls motadr bzw motptr ungültig ist.

III. Die frei definierbaren MPS_Funktionen einer DLL:

MPS_Funktionen haben grundsätzlich die Form

    void funktion_blabla( MPS_motregs *motregs )

motregs zeigt dabei auf die Liste der Motorola-Register d0-a7.Der Inhalt der Register ist schon im richtigen Intel-ByteSex.Die Motorola-Register dürfen auch mit neuen Werten beschrieben werden.

    Die DLL übergibt mit mps_get_functionlist die Liste der Adressen aller solcher MPS_Funktionen. Die Funktionsnummern entsprechen der Position der Funktion innerhalb der Liste. Soll eine Nummer freibleiben, ist als Adresse  0xffffffff (= -1) zu übergeben. Siehe auch mps_demo.cpp.

IV. Motorola-seitiger Aufruf

MPS_Funktionen werden durch einen 8-Byte-Opcode motorola-seitig aufgerufen:

    dc.w $4fbf  * 2 Bytes: nicht ändern
    dc.l DLL_ID  * 4 Bytes: DLL-spezifische DLL_ID
    dc.w Fkt_Nr.  * 2 Bytes: Funktionsnummer.

Die DLL_ID ist die über mps_get_functionlist mitgeteilte DLL_ID (4 Bytes!).  Funktionsnummer ist die Position der Funktion in der über mps_get_functionlist mitgeteilten Funktionsliste (Zählung beginnt bei 0).

 V. Sonstiges

  1. Jede DLL sollte eine individuelle DLL_ID verwenden, um Konflikte zwischen mehreren DLLs zu vermeiden (siehe mps_demo.h ) DLL_IDs mit gesetztem Bit 31 sind für uns (Application Systems) bzw. für zugeteilte IDs reserviert . Bitte wählen Sie deshalb keine DLL_ID mit  gesetztem Bit 31! Falls wir Ihnen eine reservierte DLL_ID zuteilen sollen, setzen Sie sich bitte mit Herrn Hoffmann von Application Systems in Verbindung. Ich (Dimitri Junker) werde Kennungen benutzen die in ASCII-Schreibweise mit ´DYJ´ beginnen
  2. Achten Sie auf die Verschiebung des Adressraumes!! Wollen Sie eine Motorola-Adresse DLL-seitig verwenden, ist zur Konvertierung
       intel_adr(..) bzw.
       intel_ptr(..)
       aufzurufen (siehe MPS_magicinfo in mps_base.h ).
    Adressen aus dem DLL-Adressraum  können motorola-seitig NICHT verwendet werden!
  3. Achten Sie auf den unterschiedlichen Byte-Sex zwischen Motorola- und Intel-Prozessor.
    Worte und Langworte aus dem Motorola-Adressraum müssen geswappt werden, damit sie in der DLL richtig vorliegen. Beim eventuellen zurückschreiben ist wieder zu swappen.
       Sie können dazu die Funktionen
       swap_word(..) bzw.
       swap_long(..)
    aufrufen (siehe MPS_magicinfo in mps_base.h ).
    Aber: Die Elemente von MPS_motregs (d0-a7) liegen schon intelmäßig vor und müssen nicht mehr  geswappt werden.

  ---------------------------- ENDE ---------------------------

Mit freundlichen Grüßen

  F. Schmerbeck