home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9303 / netz / tpnet / dpmi.pas next >
Encoding:
Pascal/Delphi Source File  |  1993-06-02  |  7.2 KB  |  194 lines

  1. (*========================================================*)
  2. (*                       DMPI.PAS                         *)
  3. (*             (c) 1993 G. Blumert & DMV-Verlag           *)
  4. (*--------------------------------------------------------*)
  5. (*     Compiler: Turbo-/Borland-Pascal für Windows        *)
  6. (*                                                        *)
  7. (* Funktion: Implementiert die für die Kommunikation mit  *)
  8. (* IPX nötigen Routinen. Stellt Datentypen und Routinen   *)
  9. (* fⁿr die Kommunikation mit DPMI bereit.                 *)
  10. (*      Das Programm mu▀ im Protected Mode laufen!        *)
  11. (*========================================================*)
  12.  
  13. UNIT DPMI;
  14. {$X+,B-}
  15.  
  16. INTERFACE
  17.  
  18. USES WinTypes;
  19.  
  20. TYPE
  21.   pDPMICallStruct = ^tDPMICallStruct;
  22.   tDPMICallStruct = RECORD
  23.     EDI, ESI, EBP, Reserved, EBX, EDX, ECX, EAX: LongInt;
  24.     Flags, ES, DS, FS, GS, IP, CS, SP, SS: WORD
  25.   END;
  26.  
  27. (*--------------------------------------------------------*)
  28. (* Fⁿr die Kommunikation mit DPMI ben÷tigt das            *)
  29. (* Demoprogramm 3 CALL-Strukturen                         *)
  30. (*  - eine fⁿr die CallBack-Funktion, die ja jederzeit    *)
  31. (*    aufgerufen werden kann                              *)
  32. (*  - und je eine fⁿr die Funktionen ListenForPacket und  *)
  33. (*    SendPacket.                                         *)
  34. (*                                                        *)
  35. (* Die Strukturen mⁿssen entweder statisch im Datenseg-   *)
  36. (* ment liegen oder mit GlobalAlloc reserviert werden.    *)
  37. (* Eine Reservierung mit den TPW-Routinen New, GetMem     *)
  38. (* oder MemAlloc bringt DPMI ins Schleudern, und mit      *)
  39. (* etwas Glⁿck landet man wenigstens noch am freundlichen *)
  40. (* C:\>                                                   *)
  41.  
  42. VAR
  43.   CallStrc      : pDPMICallStruct;
  44.   CallBackStrc  : pDPMICallStruct;
  45.   ListenStrc    : pDPMICallStruct;
  46.   CallStrcHandle: tHandle;  (* Es wird nur ein Handle     *)
  47.                             (* angefordert                *)
  48.  
  49. CONST
  50.   MyFunc = $0BDC5; (* Von WinNet installierte Funktion    *)
  51.                    (* des Int 2Fh                         *)
  52.  
  53. (* DOSAdr: von DPMI erhaltene Call-Back Adresse. Wird     *)
  54. (* diese vom Real-Mode aus aufgerufen, so wird eine       *)
  55. (* Protected-Mode-Routine aufgerufen, die das Datenpaket  *)
  56. (* an einem sicheren Ort speichert.                       *)
  57. (* Wird diese direkt von IPX aufgerufen, so endet das     *)
  58. (* leider mit einem Absturz (Warum? - Keine Ahnung!).     *)
  59. (* Daher liegt das Real-Mode-Programm WinNet zwischen     *)
  60. (* Windows-Anwendung und IPX.                             *)
  61. (* Der Rⁿckgabewert bezeichnet die an IPX zu ⁿbergebende  *)
  62. (* Adresse des Event-Handlers, nΣmlich den Einsprung in   *)
  63. (* WinNet, von dem aus dann erst die Call-Back-Prozedur   *)
  64. (* aufgerufen wird.                                       *)
  65. (* Speichert au▀erdem die von WinNet belegte Int.-Nummer  *)
  66. (* in RealModeInt                                         *)
  67. FUNCTION InitIpxInt(DOSAdr: POINTER): POINTER;
  68.  
  69. (* Fⁿllt die ⁿbergebene Struktur mit den ⁿbergebenen      *)
  70. (* Werten. Setzt alle anderen Felder auf 0.               *)
  71. (* DPMI stellt einen Stack von 30 Worten zur Verfⁿgung,   *)
  72. (* wenn SS:SP = NIL ist                                   *)
  73. PROCEDURE FillStruc(aStruc: pDPMICallStruct;
  74.                     ES_SI: POINTER; AX, BX, CX, DX: WORD);
  75.  
  76. (* Simuliert einen Real-Mode-Interrupt, und zwar den von  *)
  77. (* WinNet installierten                                   *)
  78. PROCEDURE RMInt(aStruc: pDPMICallStruct);
  79.  
  80. (* Gibt eine Adresse zurⁿck, die im Real-Mode             *)
  81. (* angesprungen werden kann, um die Prozedur ProcAdr zu   *)
  82. (* starten                                                *)
  83. FUNCTION GetCallBack(ProcAdr: POINTER): POINTER;
  84.  
  85. (* Call-Back-Adresse wieder freigeben. Es ist der von     *)
  86. (* GetCallBack erhaltene Pointer zurⁿckzugeben            *)
  87. PROCEDURE FreeCallBack(ProcAdr: POINTER);
  88.  
  89. IMPLEMENTATION
  90.  
  91. USES
  92. {$IFDEF Ver70} Objects, {$ELSE} WObjects, {$ENDIF} WinProcs;
  93.  
  94. CONST RealModeInt: BYTE = 0;
  95.                          (* Von WinNet belegter Interrupt *)
  96.  
  97. PROCEDURE FillStruc(aStruc: pDPMICallStruct;
  98.                     ES_SI: POINTER; AX, BX, CX, DX: WORD);
  99. BEGIN
  100.   FillChar(aStruc^, SizeOf(CallStrc^), 0);
  101.   WITH aStruc^ DO BEGIN
  102.     ES  := PtrRec(ES_SI).Seg;
  103.     ESI := PtrRec(ES_SI).Ofs;
  104.     EAX := AX;
  105.     EBX := BX;
  106.     ECX := CX;
  107.     EDX := DX
  108.   END
  109. END;
  110.  
  111. PROCEDURE RMInt(aStruc: pDPMICallStruct); ASSEMBLER;
  112. VAR Stack: LongInt;
  113. ASM
  114.   XOR   BX, BX                (* BH = 1: Interrupt-       *)
  115.                               (* Controller-Reset und A20 *)
  116.                               (* sperren                  *)
  117.   MOV   CX, BX                (* 0 Bytes von Prot.-Mode-  *)
  118.                               (* Stack auf Real-Mode      *)
  119.                               (* Stack kopieren           *)
  120.   MOV   BL, [RealModeInt]     (* BL = Interruptnummer     *)
  121.   MOV   AX, 0300H             (* Funktion $300            *)
  122.   LES   DI, [aStruc]          (* ES:DI = ^Struct          *)
  123.   Int   31H
  124. END;
  125.  
  126. FUNCTION InitIpxInt(DOSAdr: POINTER): POINTER; ASSEMBLER;
  127. ASM
  128.   MOV   AX, MyFunc
  129.   XOR   SI, SI                (* SI <> MyFunc!            *)
  130.   MOV   BX, WORD Ptr [DOSAdr]
  131.   MOV   DX, WORD Ptr [DOSAdr+2]
  132.   Int   2FH
  133.   CMP   AX, 0A5A5H            (* WinNet geladen ?         *)
  134.   JE    @WinNetGeladen
  135.   XOR   AX, AX                (* Nein!                    *)
  136.   MOV    DX, AX                (* NIL zurⁿckgeben          *)
  137.   JMP    @Ende
  138. @WinNetGeladen:
  139.   MOV   [RealModeInt], DL     (* Von WinNet belegte       *)
  140.                               (* Interruptnummer merken   *)
  141.   MOV   AX, BX                (* IPX-Eventhandler in      *)
  142.                               (* CX:BX nach DX:AX         *)
  143.   MOV   DX, CX
  144. @Ende:
  145. END;
  146.  
  147. FUNCTION GetCallBack(ProcAdr: POINTER): POINTER; ASSEMBLER;
  148. ASM
  149.   PUSH DS
  150.   LES  DI, [CallBackStrc]
  151.   LDS  SI, [ProcAdr]
  152.   MOV  AX, 0303H             (* Funktion $0303            *)
  153.   Int  31H
  154.   POP  DS
  155.   MOV  AX, DX             (* Adresse von CX:DX nach DX:AX *)
  156.   MOV  DX, CX
  157. END;
  158.  
  159. PROCEDURE FreeCallBack(ProcAdr: POINTER); ASSEMBLER;
  160. ASM
  161.   MOV  DX, WORD Ptr [ProcAdr]
  162.   MOV  CX, WORD Ptr [ProcAdr+2]
  163.   MOV  AX, 0304H             (* Funktion $0304            *)
  164.   Int  31H
  165. END;
  166.  
  167. VAR OldExitProc: POINTER;
  168.  
  169. (* Gibt den Speicher fⁿr die DPMI-Strukturen wieder frei  *)
  170. PROCEDURE MemExit; FAR;
  171. BEGIN
  172.   ExitProc := OldExitProc;
  173.   GlobalUnlock(CallStrcHandle);
  174.   GlobalFree(CallStrcHandle)
  175. END;
  176.  
  177. BEGIN
  178. (* Speicher fⁿr die DPMI-Strukturen reservieren - schont  *)
  179. (* das Datensegment                                       *)
  180.   CallStrcHandle        :=
  181.      GlobalAlloc(gMem_Moveable,SizeOf(tDPMICallStruct) * 3);
  182.   CallStrc              := GlobalLock(CallStrcHandle);
  183.   LongInt(CallBackStrc) := LongInt(CallStrc)
  184.                          + SizeOf(tDPMICallStruct);
  185.   LongInt(ListenStrc)   := LongInt(CallBackStrc)
  186.                          + SizeOf(tDPMICallStruct);
  187.   OldExitProc := ExitProc;   (* Exitprozedur installieren *)
  188.   ExitProc    := @MemExit
  189. END.
  190.  
  191. (*========================================================*)
  192. (*                     Ende von DMPI.PAS                  *)
  193.  
  194.