#$+K MPK3D: Virtueller Gerätetreiber 1.0 für isel Microstep-Steuerkarte
Das Programm MPK3D.386 ist ein virtueller Gerätetreiber (VxD) für Windows/386™, Windows™ 3.1 im Erweiterten Modus und Windows95™, jedoch nicht für Windows NT™, OS/2™ oder WinOS2. Er dient zur Ansteuerung der isel Microstep-Steuerkarte MPK-3. Diese Karte beinhaltet 3 Motortreibereinheiten. Der Treiber spricht sie - im Gegensatz zum Originaltreiber MPK3DRV.EXE - als Einzelmotoren an. Dadurch entfallen die Möglichkeiten der Proportional- (Geraden-) und Kreisbewegung.
Dagegen wurden Funktionen eingebaut, die eine bessere - auch simultane - Einzelverwaltung ermöglicht. So ist beispielsweise nur mit dem gewünschten Motor eine Referenzfahrt nötig, und während des Betriebes wird der Endkontakt nicht abgefragt, welches ansonsten zu umgehen enormen Hardwareaufwand nach sich zieht.
Gegenüber dem Original wurden die Programmparameter verbessert: 256 Mikroschritte pro Schritt (statt vorher maximal 80), maximale Verfahrgeschwindigkeit = 1024 Vollschritte pro Sekunde (bei dem angeschlossenen Motor des Versuchsaufbaus sind das ca. 5 Umdrehungen pro Sekunde), und das alles bei einer minimierten Taktfrequenz von 1024 Hz (VTD-Variante: 1000 Hz) statt 10000 Hz. Es verbraucht auch auf dem langsamsten 386PC unmerkbar wenig Rechenzeit.
Installation
Installation
Deinstallation
Programmierung
Installations-Test
Funktionsaufruf
Funktionsübersicht
Fehlercodes
Header-Dateien
Zum Test existieren z. Z. zwei Versionen, die einmal den Zeittakt von der CMOS-Uhr holen und im anderen Falle vom Timer-Schaltkreis. Der Funktionsumfang ist identisch. Weitere Assemblerschalter steuern, ob die Bremswegberechnung über eine Schleife (wenig, übersichtlicher Code, jedoch langsamer) oder über die Summenformel (unübersichtlicher Assemblercode, vorhersagbare Abarbeitungszeit) erfolgt, und ob eine Debug- oder eine Release-Version erzeugt wird.

h#s © Technische Universität Chemnitz, Fachbereich Meß- und Sensortechnik

#$+K Installation
Das Programm MPK3D.386 muß in der vorliegenden Version von Hand installiert werden. Dazu müssen Sie in der Windows-Startdatei SYSTEM.INI einige Änderungen vornehmen. Empfehlenswert ist hierzu das zu Windows mitgelieferte Programm SYSEDIT.EXE.
1.	Starte SYSEDIT.EXE mittels Programm-Manager Menüpunkt Datei | Ausführen
2.	Kopiere MPK3D.386 in das Windows-Verzeichnis
3.	Trage unter der Zeile mit [386Enh] folgende Zeile ein:
device=mpk3d.386
N1	Ersatzweise kann auch ein vollständiger Pfad angegeben werden. Das erspart das Kopieren in das Windows-Verzeichnis
N2	Die Groß/Kleinschreibung ist hierbei unbedeutend
4.	Befindet sich die isel MPK-3-Karte nicht auf der standardmäßigen Basisadresse 340h, dann ist darunter noch folgende Zeile zu ergänzen:
MPK3DPort=xxx
N3	xxx ist hierbei die hexadezimale Portadresse. MPK3D kann nicht testen, ob die Karte dort präsent ist; der Anwender muß darauf achten, daß diese Angaben korrekt sind!
5.	Windows neu starten, um diese Änderungen wirksam werden zu lassen und den Treiber zu laden.

Der Treiber kann bei Nichtgebrauch im Windows-System verbleiben, da er in diesem Fall nur unbedeutend Rechenleistung und Speicherplatz verbraucht. Die Präsenz des Treibers hat auch praktisch keinen Einfluß auf das Laufenlassen des Original-Treibers in einer DOS-Box, sofern nicht beide gleichzeitig arbeiten. Jedoch ist der Portzugriff durch das Trapping verlangsamt.
Eine nach außen sichtbare Veränderung ist die Tatsache, daß die Nur-Ausgabeports dieser Karte nun auch rücklesbar sind. Das Ausgabeport auf der Basisadresse + 6 wurde auf der Basisadresse + 7 wiederholt, da sich an Basisadresse + 6 ein echtes Eingabeport befindet.

#$+K Deinstallation (Entfernen des Treibers)
Das Programm MPK3D.386 muß in der vorliegenden Version von Hand deinstalliert werden. Dazu müssen Sie in der Windows-Startdatei SYSTEM.INI einige Änderungen vornehmen. Empfehlenswert ist hierzu das zu Windows mitgelieferte Programm SYSEDIT.EXE.
1.	Starte SYSEDIT.EXE mittels Programm-Manager Menüpunkt Datei | Ausführen
2.	Entferne die Zeile mit device=mpk3d.386 bzw. device=pfad\mpk3d.386
3	Starte Windows neu, um die Änderungen wirksam werden zu lassen

#$+K Installations-Test
Bevor ein Programm die Funktionen von MPK3D aufruft, muß es seine Anwesenheit testen. Dabei wird eine FAR (16:16)-Adresse geliefert, die fortan als Einsprungpunkt für die MPK3D-Funktionen dient. Die Einsprungpunkte stehen sowohl unter Windows als auch in einer DOS-Box (hier: sowohl Real- als auch Protected Mode) zur Verfügung, die Funktionen sind identisch. Unter Windows95 muß beim Schreiben einer 32bit-Applikation auf eine 16bit-Helfer-DLL zurückgegriffen werden, die die Zugriffe weiterreicht, da hier Interruptaufrufe nicht erlaubt sind.
Folgendes Fragment demonstriert den Installationscheck in Assembler:

EntryPoint	dd	?
MPK3_Device_ID	equ	378Ch

	xor	di,di
	mov	es,di	;ES:DI mit Null laden
	mov	bx,MPK3_Device_ID
	mov	ax,1684h
	int	2Fh
	mov	word ptr [EntryPoint],di
	mov	word ptr [EntryPoint+2],es

Mit dieser Sequenz werden generell Einsprungpunkte für VxDs angefordert. Die VxDs unterscheiden sich nur in ihrer Device_ID, die von Microsoft zentral vergeben wird. Das vermeidet Kollisionen.
Die Speicherzelle EntryPoint enthält 0 (NULL, nil), wenn das VxD MPK3D nicht präsent ist.
Ein vorhergehender Test, ob Windows im Enhanced Mode läuft, ist angeraten, aber nicht unbedingt erforderlich.

#$+K Funktionsaufruf
Der Treiber wird nur über die im Installations-Test erhaltene Adresse angesprochen. Generell werden Register mit folgender Belegung übergeben:
AH	Funktionsnummer
AL	Einheiten-Nummer. Gemeint ist hier die Motor-Nummer der Karte. 1=X, 2=Y und 3=Z.
EDX	Erster Long-Parameter (32 bit, vorzeichenbehaftet)
ECX	Zweiter Long-Parameter (32 bit, vorzeichenbehaftet)

Danach erfolgt der Aufruf, in Assembler mit
	call	[EntryPoint]

Folgende Register werden zurückgegeben:
AL	Fehlercode (das Übertragsflag CY ist zudem gesetzt), Null wenn fehlerfrei (dann Carry-Flag gelöscht)
EDX	Erster Long - Rückgabewert oder zerstört (32bit, vorzeichenbehaftet)
ECX	Zweiter Long - Rückgabewert oder zerstört (32bit, vorzeichenbehaftet)

Alle anderen Register werden unverändert belassen.

#$+K Funktionsübersicht
Folgende Funktionen stehen zur Verfügung:
Funktion 0: Keine Funktion [SM_Nop]
Funktion 1: Motorspulen stromlos machen [SM_Free]
Funktion 2: Referenzfahrt [SM_Sync]
Funktion 3: Absolute Bewegung [SM_MoveAbs]
Funktion 4: Relative Bewegung [SM_MoveRel]
Funktion 5: Motor zuweisen und belegen [SM_Assign]
Funktion 6: Motor freigeben [SM_UnAssign]
Funktion 7: Geschwindigkeit und Beschleunigung festlegen [SM_SetSA]
Funktion 8: Geschwindigkeit und Beschleunigung erfragen [SM_GetSA]
Funktion 9: PostMessage-Adresse sowie Fensterhandle und Nachricht festlegen [SM_SetPostMsg]
Funktion 10: PostMessage-Adresse sowie Fensterhandle und Nachricht erfragen [SM_GetPostMsg]
Funktion 11: Aktuelle Position und Geschwindigkeit erfragen [SM_GetPosition]
Funktion 12: Bereichsgrenzen setzen [SM_SetBounds]
Funktion 13: Bereichsgrenzen erfragen [SM_GetBounds]
Funktion 14: Soforthalt [SM_Stop]
Funktion 15: (Getriebe-) Übersetzungsverhältnis setzen [SM_SetGear]
Funktion 16: (Getriebe-) Übersetzungsverhältnis erfragen [SM_GetGear]
Funktion 17: Hardware-Endschalter-Maske u. a. m. setzen [SM_SetHWE]
Vor dem Aufruf der Funktionen muß der Installationstest erfolgen, um die Einsprungadresse zu ermitteln. Die Funktionen 2, 3, 4, 7, 8, 11, 12 und 13 arbeiten mit Anwenderkoordinaten, die intern mit dem angegebenen Getriebeverhältnis umgerechnet werden.

#$+K Funktion 0: Keine Funktion [SM_Nop]
Diese Funktion tut schlichtweg nichts. Sie liefert immer den Fehlercode AL=0
Entsprechung: Abfrage der Treiberversion, Funktion 0
Parameter: AH=0, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: Keine (Evtl. Versionsnummer)
Mögliche Fehlercodes: 0

#$+K Funktion 1: Motorspulen stromlos machen [SM_Free]
Diese Funktion schaltet den Strom durch die Motorspulen ab. Dadurch ist es leicht möglich, die Achse mit der Hand zu bewegen. Da hierbei der rechnerinterne Bezug zur Position fehlt, wird diese für ungültig erklärt; für nachfolgende Bewegungen ist eine Referenzfahrt vonnöten.
Entsprechung: Diese Funktion entspricht dem Einschalten des Handmodus', Funktion 8
Parameter: AH=1, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: Keine
Mögliche Fehlercodes: 0, 4, 50

#$+K Funktion 2: Referenzfahrt [SM_Sync]
Diese Funktion führt eine Referenzfahrt durch. Der Motor bewegt sich dabei bis zu seinem Endlagenschalter. Wenn er diesen erreicht, stellt er die interne Position auf den in EDX angegebenen Wert, d.h. der Endlagenkontakt muß nicht bei Null liegen.
Die Referenzfahrt erfolgt ohne Beschleunigungs- und Bremsphase, d.h. der Anlauf und der Halt erfolgen ruckartig. Daher darf die Geschwindigkeit nicht zu hoch gewählt werden, um Schrittverluste zu vermeiden und die angeschlossene Apparatur zu schonen.
Entsprechung: Referenzfahrt, Funktion 6
Parameter: AH=2, AL=Motor-Nummer (1=X, 2=Y, 3=Z), EDX=Position des Endschalters, Vorzeichen von ECX ist Richtungsangabe der Schaltersuche. Ist ECX betragsmäßig >=1, wird ECX als Referenzgeschwindigkeit herangezogen.
Rückgabe: Keine; Benachrichtigung bei Fertigstellung.
Mögliche Fehlercodes: 0, 4, 50

#$+K Funktion 3: Absolute Bewegung [SM_MoveAbs]
Diese Funktion bewegt die Motorachse zu der in EDX angegebenen Absolutposition.
Entsprechung: Absolute Linearnormalbewegung, Funktion 25
Parameter: AH=3, AL=Motor-Nummer (1=X, 2=Y, 3=Z), EDX=Zielposition
Rückgabe: Keine; Benachrichtigung bei Fertigstellung
Mögliche Fehlercodes: 0, 4, 5, 9, 50

#$+K Funktion 4: Relative Bewegung [SM_MoveRel]
Diese Funktion bewegt die Motorachse um den in EDX angegebenen vorzeichenbehafteten Betrag.
Entsprechung: Relative Linearnormalbewegung, Funktion 24
Parameter: AH=4, AL=Motor-Nummer (1=X, 2=Y, 3=Z), EDX=Differenz
Rückgabe: Keine; Benachrichtigung bei Fertigstellung
Mögliche Fehlercodes: 0, 4, 5, 9, 50

#$+K Funktion 5: Motor zuweisen und belegen [SM_Assign]
Diese Funktion belegt den angegebenen Motor, d.h. es können mit ihm Aktionen ausgeführt werden, und der Motor ist für andere Prozesse als belegt markiert. Der Spulenstrom wird abgeschaltet und die Leistungsendstufen ggf. eingeschaltet. Die Werte für Geschwindigkeit und Beschleunigung werden auf Standardwerte gesetzt, der abfahrbare Bereich umfaßt -MaxLong..MaxLong, das Getriebeverhältnis wird auf 1:1 gesetzt.
Entsprechung: keine
Parameter: AH=5, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: Keine
Mögliche Fehlercodes: 0, 51

#$+K Funktion 6: Motor freigeben [SM_UnAssign]
Diese Funktion gibt den angegebenen Motor frei. Der Spulenstrom wird abgeschaltet sowie gegebenenfalls auch die Leistungsendstufen. Diese Funktion arbeitet nicht während der Bewegung!
Entsprechung: keine
Parameter: AH=6, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: Keine
Mögliche Fehlercodes: 0, 4, 50

#$+K Funktion 7: Geschwindigkeit und Beschleunigung festlegen [SM_SetSA]
Diese Funktion legt die Maximalgeschwindigkeit und die Maximalbeschleunigung während einer Bewegungsphase fest. In diese Angaben fließt der Zeittakt von 1024 Hz ein.
Während der Bewegung ausgeführt, hat diese Funktion unmittelbaren Einfluß auf die momentane Bewegung.
Entsprechung: Setzen der Segmentgeschwindigkeit, Funktion 20
Parameter: AH=7, AL=Motor-Nummer (1=X, 2=Y, 3=Z), EDX=Geschw., ECX=Beschl
Rückgabe: EDX=vorherige Geschw., ECX=vorherige Beschl.
Mögliche Fehlercodes: 0, 50

#$+K Funktion 8: Geschwindigkeit und Beschleunigung erfragen [SM_GetSA]
Diese Funktion fragt die Maximalgeschwindigkeit und die Maximalbeschleunigung ab. In diese Angaben fließt der Zeittakt von 1024 Hz ein.
Entsprechung: keine
Parameter: AH=8, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: EDX=Geschwindigkeit, ECX=Beschleunigung
Mögliche Fehlercodes: 0, 50

#$+K Funktion 9: PostMessage-Adresse sowie Fensterhandle und Nachricht festlegen [SM_SetPostMsg]
Diese Funktion setzt die Adresse für PostMessage, da dies das VxD leider nicht selbst tun kann. Außerdem wird das Fensterhandle und die Nachricht festgelegt. Bei Fertigstellung einer Bewegung (Referenzfahrt oder Bewegung) wird an das angegebene Fensterhandle die angegebene Botschaft mittels PostMessage in die Nachrichtenwarteschlange geschickt. Das Programm kann so ohne aufwendiges Polling auf die Fertigstellung reagieren. In wParam wird z.Z. 0 übergeben, in lParam steht die Position.
Der Aufruf dieser Funktion macht nur unter Windows Sinn, nicht in einer DOS-Anwendung, da das Call-Out immer in die System-VM, also zum "richtigen" Windows hin erfolgt.
Entsprechung: keine
Parameter: AH=9, AL=Motor-Nummer (1=X, 2=Y, 3=Z), EDX=FAR (16:16)-Adresse von PostMessage, ECX = Fensterhandle + 65536 · Botschaftscode
Rückgabe: EDX=vorherige Adresse, ECX=vorheriges Fensterhandle und Botschaftscode
Mögliche Fehlercodes: 0, 50

#$+K Funktion 10: PostMessage-Adresse sowie Fensterhandle und Nachricht erfragen [SM_GetPostMsg]
Diese Funktion liefert die mit Funktion 9 gesetzten Werte zurück.
Entsprechung: keine
Parameter: AH=9, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: EDX=vorherige Adresse, ECX=vorheriges Fensterhandle und Botschaftscode
Mögliche Fehlercodes: 0, 50

#$+K Funktion 11: Aktuelle Position und Geschwindigkeit erfragen [SM_GetPosition]
Diese Funktion liefert die momentane Position und Geschwindigkeit. Die Geschwindigkeit ergibt sich aus dem Zeittakt von 1024 Hz.
Entsprechung: Abfragen der Istpositionen und Istgeschwindigkeit, Funktionen 18 und 19
Parameter: AH=11, AL=Motor-Nummer (1=X, 2=Y, 3=Z)
Rückgabe: EDX=Istposition (vzb.), ECX=Istgeschwindigkeit (vorzeichenlos!)
Ist EDX=INVPOS, ist die Position unbestimmt.
Mögliche Fehlercodes: 0, 50

#$+K Funktion 12: Bereichsgrenzen setzen [SM_SetBounds]
Diese Funktion setzt Bereichsgrenzen, in der Bewegungen möglich sind, sozusagen als zusätzlicher Schutz vor wildgewordenen Programmen
Entsprechung: Setzen der Software-Endschalter, Funktion 14
Parameter: AH = 12, AL = Motornummer (1=X, 2=Y, 3=Z), EDX = Untere Grenze, ECX = Obere Grenze
Rückgabe: EDX = vorherige untere Grenze, ECX = vorherige obere Grenze
Mögliche Fehlercodes: 0, 50

#$+K Funktion 13: Bereichsgrenzen erfragen [SM_GetBounds]
Diese Funktion erfragt die von der vorherigen Funktion gesetzten Bereichsgrenzen
Entsprechung: keine
Parameter: AH = 13, AL = Motornummer (1=X, 2=Y, 3=Z)
Rückgabe: EDX = untere Grenze, ECX = obere Grenze
Mögliche Fehlercodes: 0, 50

#$+K Funktion 14: Soforthalt [SM_Stop]
Diese Funktion stoppt sofort alle Bewegungen (Referenzfahrt und Bewegung). Der Spulenstrom wird nicht abgeschaltet, um die Bremswirkung zu erhöhen. Es wird kein PostMessage ausgesendet.
Entsprechung: Ausschalten des Handmodus', Funktion 8
Parameter: AH = 14, AL = Motornummer (1=X, 2=Y, 3=Z)
Rückgabe: keine
Mögliche Fehlercodes: 0, 50

#$+K Funktion 15: (Getriebe-) Übersetzungsverhältnis setzen [SM_SetGear]
Diese Funktion setzt das Getriebeverhältnis. Statt einer Gleit- oder Festkommazahl wurde hier ein Bruch eingeführt, mit dem es sich in Assembler gut rechnen läßt und der auch mechanisch seine Entsprechung hat. Als Zähler sollte angegeben werden, wieviele Anwender-Einheiten z.B. ein Millimeter oder eine Umdrehung sein soll; als Nenner, wieviele Mikroschritte (Ganzschritte*256) der vorhandene Antrieb tatsächlich für denselben Millimeter bzw. dieselbe Umdrehung benötigt. Eine Drehrichtungsumkehr kann erwirkt werden, wenn genau einer der beiden Parameter negativ ist.
Voreingestellt ist das Übersetzungsverhältnis 1:1.
Entsprechung: keine dokumentierte Funktion; steht in der INI-Datei
Parameter: AH = 15, AL = Motornummer (1=X, 2=Y, 3=Z), EDX = Zähler, ECX = Nenner
ECX bzw. EDX werden jeweils nicht übernommen, wenn sie Null sind. Dann wird nur der alte Wert zurückgeliefert.
Rückgabe: EDX = vorheriger Zähler, ECX = vorheriger Nenner
Mögliche Fehlercodes: 0, 50

#$+K Funktion 16: (Getriebe-) Übersetzungsverhältnis erfragen [SM_GetGear]
Diese Funktion fragt das gesetzte Getriebeverhältnis ab. Siehe vorherige Funktion.
Entsprechung: keine dokumentierte Funktion; steht in der INI-Datei
Parameter: AH = 16, AL = Motornummer (1=X, 2=Y, 3=Z)
Rückgabe: EDX = Zähler, ECX = Nenner
Mögliche Fehlercodes: 0, 50

#$+K Funktion 17: Hardware-Endschalter-Maske u. a. m. setzen [SM_SetHWE]
Diese Funktion setzt die Hardwareendschaltermaske, die zu den Motorspulen gehörigen Portadressen, ein Schaltbit, ob der Hardware‑endschalter (HWE) während der normalen Bewegung weiterhin überwacht werden soll, sowie ein Schaltbit, ob sinus- oder dreieckförmiger Stromverlauf gewünscht wird.
Entsprechung: keine dokumentierte Funktion; fest im Programmcode von MPK3DRV.EXE eingebaut
Parameter: AH = 17, AL = Motornummer (1=X, 2=Y, 3=Z),
DL: AND-Maske für HWE; DH: XOR-Maske für HWE. Ist DX = 0, erfolgt kein Setzen dieser Werte.
Bit16(EDX): Überwachung des Hardwareendschalters EIN, wenn = 1; Bit17(EDX): Dreieckform, wenn = 1, Sinusform, wenn = 0
CL: Portadressen-Offset für System A (0..5), CH: Portadressen-Offset für System B (0..5). Ist CX = 0, erfolgt kein Setzen dieser Werte.
Rückgabe: DX = alte Werte für AND- und XOR-Maske, CX = alte Werte für Portadressen-Offsets
Mögliche Fehlercodes: 0, 50
Hinweis: Die Werte für die Portadressen gelten bis zum Ende der Windows-Sitzung, d.h. ein automatisches Rücksetzen beim Zuweisen wie bei allen anderen Einstellungen erfolgt hier NICHT. Die Feststellung, ob ein Hardwareendschalter anspricht, erfolgt nach folgendem Schema:

	mov	dx,[PortBase]
	add	dx,6		;OffsetHWE
	in	al,dx
	xor	al,[XorMask]
	and	al,[AndMask]
	jnz	Endschalter_betaetigt

Diese Einstellungen ermöglichen eine wahlfreie Zuordnung zwischen den Motor-Systemen und den 6 identischen Stromtreibern auf der Platine. Durch Vertauschen des Systems A und B eines Motors erfolgt beispielsweise eine Drehrichtungsumkehr. Durch die wahlfreie Zuordnung der HWE ist es außerdem möglich, die Opto-Eingänge als Endschalter zu gebrauchen, die Polarität frei zu wählen sowie mehrere Schalter gleichzeitig auf ODER-Basis zu überwachen.

#$+K Fehlercodes
Folgende Fehler können beim Aufruf der MPK3D-Funktionen auftreten:
AL=0	Kein Fehler
AL=1	Falsche Funktionsnummer. Die angegebene Funktionsnummer (AH) existiert nicht
AL=4	In Bewegung. MPK3D ist nicht in der Lage, diese Funktion auszuführen, da gerade eine Bewegung erfolgt. Abwarten, STOP ausführen oder auf Nachricht warten.
AL=5	Bereichsüberlauf. Der angegebene Zielpunkt bei einer Bewegung schießt über die Grenzen hinaus; die Bewegung wird nicht ausgeführt. Im Bereich bleiben; der Bereich ist abfragbar.
AL=7	Während der Bewegung trat der Hardware-Endschalter unerwartet in Aktion. Nicht implementiert.
AL=9	Keine Referenz. Der momentane Punkt des Schrittmotors ist unbestimmt. Es kann keine Bewegung ausgeführt werden. Referenzfahrt durchführen!
AL=50	Nicht zugewiesen. Die angegebene Motornummer wurde noch nicht zugewiesen.
AL=51	Bereits zugewiesen. Die angegebene Motornummer ist bereits zugewiesen und damit belegt.
AL=52	Kein Motor. Die angegebene Motornummer existiert nicht (AL=0 oder AL>3).

Die Fehlercodes <50 entsprechen denen des Originaltreibers MPK3DRV.EXE.

Folgende Konstanten sind in den Headerdateien deklariert:
ME_NoError	0
ME_WrongFunction	1
ME_InMove	4
ME_SoftEnd	5
ME_HardEnd	7
ME_NoRef	9
ME_NotAssigned	50
ME_AlreadyAssigned	51
ME_NoDriver	52

Außerdem noch eine Konstante zur Darstellung der ungültigen Position:
INVPOS	80000000h (also in Pascal $80000000 und in C 0x80000000)

#$+K Header-Dateien
Zu dem Treiber gibt es Headerdateien zum Ansprechen des VxDs aus einer Hochsprache. Es existieren sowohl Dateien für C (MPK3D.H und MPK3D.C) sowie Pascal (MPK3D.PAS). Darin deklariert ist der obligatorische Einsprungpunkt (ein FAR (16:16)-Zeiger), einige Konstanten, eine Initialisierungsprozedur (bei Pascal wird diese automatisch beim Einbinden der Unit gerufen) sowie zwei Zugriffsfunktionen VxDsupC und VxDsupV. Diese unterscheiden sich dadurch, daß mit der zweiten Funktion eine Parameter-Rückgabe möglich ist.

Pascal:
var EntryPoint: Pointer;
function VxDsupC(AFunc, AUnit:Byte; lParam1,lParam2:LongInt):Byte;
function VxDsupV(AFunc, AUnit:Byte; var lParam1,lParam2:LongInt):Byte;

C:
void far *EntryPoint;
typedef unsigned char byte;
void VxDInit(void);
byte VxDsupC(byte AFunc, byte AUnit, long lParam1, long lParam2);
byte VxDsupV(byte AFunc, byte AUnit, long *lParam1, long *lParam2);
Parameter:
AFunc	Funktionsnummer, wird in AH dem VxD übergeben
AUnit	Motornummer, wird in AL dem VxD übergeben
lParam1	Erster Long-Parameter, EDX beim VxD-Ein- und Austritt
lParam2	Zweiter Long-Parameter, ECX beim VxD-Ein- und Austritt

Rückgabewert:
Die Funktionen liefern den Fehlercode der VxD-Funktion.

Hinweis: Bei der C-Variante muß der Anwender die VxDInit()-Funktion aufrufen. Bei Pascal geschieht das einfach durch Einbinden der Unit (im Initialisierungsteil).
Innerhalb der Funktionen CxDsupC und VxDsupV erfolgt ein Test, ob der EntryPoint ungleich Null ist. Wenn nein, wird die Funktion nicht gerufen, und der Rückgabewert ist undefiniert.
Das Anwenderprogramm sollte auf jeden Fall die Präsenz eines 386-Prozessors prüfen. In Turbo Pascal geschieht dies einfach durch Überprüfen von Test8086>=2.

Funktionsübersicht

#$K MPK3D Virtueller Gerätetreiber für Windows zur isel Microstep-Steuerkarte
h#s © Technische Universität Chemnitz, Fachbereich Meß- und Sensortechnik