2
0

pmode.pas 5.8 KB

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