pmode.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. {
  2. This file is part of the Free Sockets Interface
  3. Copyright (c) 1999 by Berczi Gabor
  4. Support routines for DPMI programs
  5. See the file COPYING.FCL, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit PMode;
  12. {$H-}
  13. interface
  14. uses Dos;
  15. type
  16. MemPtr = object
  17. Ofs,Seg: word;
  18. Size : word;
  19. Sel : word;
  20. function DosPtr: pointer;
  21. function DataPtr: pointer;
  22. function DosSeg: word;
  23. function DosOfs: word;
  24. procedure MoveDataTo(var Src; DSize: word);
  25. procedure MoveDataFrom(DSize: word; var Dest);
  26. procedure Clear;
  27. private
  28. function DataSeg: word;
  29. function DataOfs: word;
  30. end;
  31. PtrRec = packed record
  32. Ofs,Seg: word;
  33. end;
  34. registers32 = packed record { DPMI call structure }
  35. EDI : LongInt;
  36. ESI : LongInt;
  37. EBP : LongInt;
  38. Reserved: LongInt;
  39. EBX : LongInt;
  40. EDX : LongInt;
  41. ECX : LongInt;
  42. EAX : LongInt;
  43. Flags : Word;
  44. ES : Word;
  45. DS : Word;
  46. FS : Word;
  47. GS : Word;
  48. IP : Word;
  49. CS : Word;
  50. SP : Word;
  51. SS : Word;
  52. end;
  53. pregisters = ^registers;
  54. function GetDosMem(var M: MemPtr; Size: word): boolean;
  55. procedure FreeDosMem(var M: MemPtr);
  56. procedure realintr(IntNo: byte; var r: registers);
  57. {procedure realintr32(IntNo: byte; var r: registers32);}
  58. procedure realcall(Proc: pointer; var r: registers);
  59. function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
  60. function MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
  61. procedure realGetIntVec(IntNo: byte; var P: pointer);
  62. function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
  63. procedure freermcallback(RealCallAddr: pointer);
  64. function MakePtr(ASeg,AOfs: word): pointer;
  65. implementation
  66. {$ifdef GO32V2}
  67. { --------------------- GO32 --------------------- }
  68. uses go32;
  69. function GetDosMem(var M: MemPtr; Size: word): boolean;
  70. var L: longint;
  71. begin
  72. M.Size:=Size;
  73. L:=global_dos_alloc(Size);
  74. M.Seg:=(L shr 16); M.Ofs:=0;
  75. M.Sel:=(L and $ffff);
  76. GetDosMem:=M.Seg<>0;
  77. end;
  78. procedure FreeDosMem(var M: MemPtr);
  79. begin
  80. if M.Size=0 then Exit;
  81. if M.Sel<>0 then
  82. if global_dos_free(M.Sel)=false then
  83. writeln('!!!Failed to deallocate Dos block!!!');
  84. FillChar(M,SizeOf(M),0);
  85. end;
  86. procedure realintr(IntNo: byte; var r: registers);
  87. var rr: trealregs;
  88. begin
  89. rr.realeax:=r.ax;
  90. rr.realebx:=r.bx;
  91. rr.realecx:=r.cx;
  92. rr.realedx:=r.dx;
  93. rr.realesi:=r.si;
  94. rr.realedi:=r.di;
  95. rr.reales:=r.es;
  96. rr.realds:=r.ds;
  97. go32.realintr(IntNo,rr);
  98. r.ax:=rr.realeax and $ffff;
  99. r.bx:=rr.realebx and $ffff;
  100. r.cx:=rr.realecx and $ffff;
  101. r.dx:=rr.realedx and $ffff;
  102. r.si:=rr.realesi and $ffff;
  103. r.di:=rr.realedi and $ffff;
  104. r.es:=rr.reales and $ffff;
  105. r.ds:=rr.realds and $ffff;
  106. end;
  107. function dorealcall(var regs : trealregs) : boolean;
  108. begin
  109. regs.realsp:=0;
  110. regs.realss:=0;
  111. asm
  112. movw $0x0,%bx
  113. xorl %ecx,%ecx
  114. movl regs,%edi
  115. { es is always equal ds }
  116. movl $0x301,%eax
  117. int $0x31
  118. setnc %al
  119. movb %al,__RESULT
  120. end;
  121. end;
  122. procedure realcall(Proc: pointer; var r: registers);
  123. var rr: trealregs;
  124. begin
  125. rr.realeax:=r.ax;
  126. rr.realebx:=r.bx;
  127. rr.realecx:=r.cx;
  128. rr.realedx:=r.dx;
  129. rr.realesi:=r.si;
  130. rr.realedi:=r.di;
  131. rr.reales:=r.es;
  132. rr.realds:=r.ds;
  133. rr.flags:=r.flags;
  134. rr.CS:=PtrRec(Proc).Seg;
  135. rr.IP:=PtrRec(Proc).Ofs;
  136. rr.realss:=0; rr.realsp:=0;
  137. dorealcall(rr);
  138. r.ax:=rr.realeax and $ffff;
  139. r.bx:=rr.realebx and $ffff;
  140. r.cx:=rr.realecx and $ffff;
  141. r.dx:=rr.realedx and $ffff;
  142. r.si:=rr.realesi and $ffff;
  143. r.di:=rr.realedi and $ffff;
  144. r.es:=rr.reales and $ffff;
  145. r.ds:=rr.realds and $ffff;
  146. r.flags:=rr.Flags and $ffff;
  147. end;
  148. function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
  149. begin
  150. dosmemget(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
  151. MoveDosToPM:=true;
  152. end;
  153. function MovePMToDos(PMPtr, DosPtr: pointer; Size: word): boolean;
  154. begin
  155. dosmemput(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
  156. MovePMToDos:=true;
  157. end;
  158. procedure realGetIntVec(IntNo: byte; var P: pointer);
  159. var si: tseginfo;
  160. begin
  161. get_rm_interrupt(IntNo,si);
  162. PtrRec(P).Seg:=si.segment; PtrRec(P).Ofs:=longint(si.offset);
  163. end;
  164. procedure MemPtr.MoveDataTo(var Src; DSize: word);
  165. begin
  166. dpmi_dosmemput(DosSeg,DosOfs,Src,DSize);
  167. end;
  168. procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
  169. begin
  170. dpmi_dosmemget(DosSeg,DosOfs,Dest,DSize);
  171. end;
  172. procedure MemPtr.Clear;
  173. begin
  174. dpmi_dosmemfillchar(DosSeg,DosOfs,Size,#0);
  175. end;
  176. function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
  177. var s: tseginfo;
  178. P: pointer;
  179. begin
  180. if get_rm_callback(PMAddr,RealRegs^,s) then
  181. P:=MakePtr(s.segment,longint(s.offset))
  182. else
  183. P:=nil;
  184. allocrmcallback:=P;
  185. end;
  186. procedure freermcallback(RealCallAddr: pointer);
  187. var s: tseginfo;
  188. begin
  189. s.segment:=PtrRec(RealCallAddr).seg;
  190. s.offset:=pointer(longint(PtrRec(RealCallAddr).ofs));
  191. free_rm_callback(s);
  192. end;
  193. {$endif GO32V2}
  194. { ---------------------- COMMON ---------------------- }
  195. function MemPtr.DosPtr: pointer;
  196. begin
  197. DosPtr:=MakePtr(Seg,Ofs);
  198. end;
  199. function MemPtr.DataPtr: pointer;
  200. begin
  201. DataPtr:=MakePtr(DataSeg,DataOfs);
  202. end;
  203. function MemPtr.DataSeg: word;
  204. begin
  205. DataSeg:=Sel;
  206. end;
  207. function MemPtr.DataOfs: word;
  208. begin
  209. DataOfs:=0;
  210. end;
  211. function MemPtr.DosSeg: word;
  212. begin
  213. DosSeg:=Seg;
  214. end;
  215. function MemPtr.DosOfs: word;
  216. begin
  217. DosOfs:=Ofs;
  218. end;
  219. function MakePtr(ASeg, AOfs: word): pointer;
  220. var P: pointer;
  221. begin
  222. with PtrRec(P) do
  223. begin
  224. Seg:=ASeg; Ofs:=AOfs;
  225. end;
  226. MakePtr:=P;
  227. end;
  228. END.