pmode.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. {
  2. $Id$
  3. This file is part of the Free Sockets Interface
  4. Copyright (c) 1999 by Berczi Gabor
  5. Support routines for DPMI programs
  6. See the file COPYING.FCL, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$ifdef VER70}{$define TP}{$endif}
  13. unit PMode;
  14. interface
  15. uses Dos;
  16. type
  17. MemPtr = object
  18. Ofs,Seg: word;
  19. Size : word;
  20. {$ifdef DPMI}
  21. Sel : word;
  22. {$endif}
  23. function DosPtr: pointer;
  24. function DataPtr: pointer;
  25. function DosSeg: word;
  26. function DosOfs: word;
  27. procedure MoveDataTo(var Src; DSize: word);
  28. procedure MoveDataFrom(DSize: word; var Dest);
  29. procedure Clear;
  30. private
  31. function DataSeg: word;
  32. function DataOfs: word;
  33. end;
  34. PtrRec = packed record
  35. Ofs,Seg: word;
  36. end;
  37. registers32 = packed record { DPMI call structure }
  38. EDI : LongInt;
  39. ESI : LongInt;
  40. EBP : LongInt;
  41. Reserved: LongInt;
  42. EBX : LongInt;
  43. EDX : LongInt;
  44. ECX : LongInt;
  45. EAX : LongInt;
  46. Flags : Word;
  47. ES : Word;
  48. DS : Word;
  49. FS : Word;
  50. GS : Word;
  51. IP : Word;
  52. CS : Word;
  53. SP : Word;
  54. SS : Word;
  55. end;
  56. pregisters = ^registers;
  57. function GetDosMem(var M: MemPtr; Size: word): boolean;
  58. procedure FreeDosMem(var M: MemPtr);
  59. procedure realintr(IntNo: byte; var r: registers);
  60. {procedure realintr32(IntNo: byte; var r: registers32);}
  61. procedure realcall(Proc: pointer; var r: registers);
  62. function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
  63. function MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
  64. procedure realGetIntVec(IntNo: byte; var P: pointer);
  65. function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
  66. procedure freermcallback(RealCallAddr: pointer);
  67. function MakePtr(ASeg,AOfs: word): pointer;
  68. implementation
  69. {$ifdef TP}
  70. {$ifdef DPMI}uses WinAPI;{$endif}
  71. {$IFDEF DPMI}
  72. const
  73. DPMI_INTR = $31;
  74. type
  75. TDPMIRegisters = {$ifdef TP}Registers32{$else}TRegisters32{$endif};
  76. var
  77. DPMIRegs: TDPMIRegisters;
  78. {$ENDIF DPMI}
  79. procedure realintr(IntNo: byte; var r: registers);
  80. {$ifdef DPMI}
  81. var Regs: Registers;
  82. begin
  83. FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  84. DPMIRegs.EAX := r.ax;
  85. DPMIRegs.EBX := r.bx;
  86. DPMIRegs.ECX := r.cx;
  87. DPMIRegs.EDX := r.dx;
  88. DPMIRegs.EDI := r.di;
  89. DPMIRegs.ESI := r.si;
  90. DPMIRegs.EBP := r.bp;
  91. DPMIRegs.DS := r.ds;
  92. DPMIRegs.ES := r.es;
  93. DPMIRegs.Flags := r.flags;
  94. Regs.AX := $0300;
  95. Regs.BL := IntNo;
  96. Regs.BH := 0;
  97. Regs.CX := 0;
  98. Regs.ES := Seg(DPMIRegs);
  99. Regs.DI := Ofs(DPMIRegs);
  100. Intr(DPMI_INTR, Regs);
  101. r.ax := DPMIRegs.EAX;
  102. r.bx := DPMIRegs.EBX;
  103. r.cx := DPMIRegs.ECX;
  104. r.dx := DPMIRegs.EDX;
  105. r.di := DPMIRegs.EDI;
  106. r.si := DPMIRegs.ESI;
  107. r.bp := DPMIRegs.EBP;
  108. r.ds := DPMIRegs.DS;
  109. r.es := DPMIRegs.ES;
  110. r.Flags := DPMIRegs.Flags;
  111. end;
  112. {$else}
  113. begin
  114. intr(IntNo,r);
  115. end;
  116. {$endif}
  117. (*procedure realintr32(IntNo: byte; var r: registers32);
  118. {$ifdef DPMI}
  119. var Regs: Registers;
  120. begin
  121. FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  122. DPMIRegs:=r;
  123. Regs.AX := $0300;
  124. Regs.BL := IntNo;
  125. Regs.BH := 0;
  126. Regs.CX := 0;
  127. Regs.ES := Seg(DPMIRegs);
  128. Regs.DI := Ofs(DPMIRegs);
  129. Intr(DPMI_INTR, Regs);
  130. r:=DPMIRegs;
  131. end;
  132. {$else}
  133. begin
  134. { not implemented }
  135. Halt(99);
  136. end;
  137. {$endif}
  138. *)
  139. {$ifndef DPMI}
  140. const DummyIntRedir: boolean = false;
  141. CallAddr: pointer = nil;
  142. DummyInt = $ef;
  143. procedure CallInt; assembler;
  144. asm
  145. push ax
  146. push ds
  147. mov ax, seg CallAddr
  148. mov ds, ax
  149. mov ax, ds:CallAddr.word[0]
  150. mov cs:@JmpAddr.word[0], ax
  151. mov ax, ds:CallAddr.word[2]
  152. mov cs:@JmpAddr.word[2], ax
  153. pop ds
  154. pop ax
  155. sti
  156. db $9a
  157. @JmpAddr:
  158. dw 0,0
  159. jmp @over
  160. @regax: dw 0
  161. @over:
  162. mov word ptr cs:@regax, ax
  163. push bx
  164. pushf
  165. pop ax
  166. mov bx, sp
  167. mov word ptr ss:[bx+6], ax
  168. pop bx
  169. mov ax, word ptr cs:@regax
  170. iret
  171. end;
  172. {$endif}
  173. procedure realcall(Proc: pointer; var r: registers);
  174. {$ifdef DPMI}
  175. var Regs: Registers;
  176. begin
  177. FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  178. DPMIRegs.EAX := r.ax;
  179. DPMIRegs.EBX := r.bx;
  180. DPMIRegs.ECX := r.cx;
  181. DPMIRegs.EDX := r.dx;
  182. DPMIRegs.EDI := r.di;
  183. DPMIRegs.ESI := r.si;
  184. DPMIRegs.EBP := r.bp;
  185. DPMIRegs.DS := r.ds;
  186. DPMIRegs.ES := r.es;
  187. DPMIRegs.Flags := r.flags;
  188. DPMIRegs.CS := PtrRec(Proc).Seg;
  189. DPMIRegs.IP := PtrRec(Proc).Ofs;
  190. DPMIRegs.SS :=0; DPMIRegs.SP:=0;
  191. Regs.AX := $0301;
  192. Regs.BH := 0;
  193. Regs.CX := 0;
  194. Regs.ES := Seg(DPMIRegs);
  195. Regs.DI := Ofs(DPMIRegs);
  196. Intr(DPMI_INTR, Regs);
  197. r.ax := DPMIRegs.EAX and $ffff;
  198. r.bx := DPMIRegs.EBX and $ffff;
  199. r.cx := DPMIRegs.ECX and $ffff;
  200. r.dx := DPMIRegs.EDX and $ffff;
  201. r.di := DPMIRegs.EDI and $ffff;
  202. r.si := DPMIRegs.ESI and $ffff;
  203. r.bp := DPMIRegs.EBP and $ffff;
  204. r.ds := DPMIRegs.DS;
  205. r.es := DPMIRegs.ES;
  206. r.Flags := DPMIRegs.Flags and $ffff;
  207. end;
  208. {$else}
  209. (*begin
  210. asm
  211. push ds
  212. push bp
  213. mov ax, Proc.word[2]
  214. mov bx, Proc.word[0]
  215. mov cs:@Call+1.word, bx
  216. mov cs:@Call+3.word, ax
  217. lds si, r
  218. mov @rptr.word[2], ds
  219. mov @rptr.word[0], si
  220. lodsw
  221. push ax { -> ax }
  222. lodsw
  223. mov bx, ax
  224. lodsw
  225. mov cx, ax
  226. lodsw
  227. mov dx, ax
  228. lodsw
  229. mov bp, ax
  230. lodsw
  231. push ax { -> si }
  232. lodsw
  233. mov di, ax
  234. lodsw
  235. push ax { -> ds }
  236. lodsw
  237. mov es, ax
  238. lodsw
  239. push ax { -> flags }
  240. popf
  241. pop si
  242. pop ds
  243. pop ax
  244. @Call:
  245. db 9ah
  246. dd 0
  247. jmp @skipover
  248. @rptr: dd 0
  249. @skipover:
  250. pushf
  251. push es
  252. push di
  253. mov es, @rptr.word[2]
  254. mov di, @rptr.word[0]
  255. stosw
  256. mov ax, bx
  257. stosw
  258. mov ax, cx
  259. stosw
  260. mov ax, dx
  261. stosw
  262. mov ax, bp
  263. stosw
  264. mov ax, si
  265. stosw
  266. pop ax { <- di }
  267. stosw
  268. mov ax, ds
  269. stosw
  270. pop ax { <- es }
  271. stosw
  272. pop ax { <- flags }
  273. stosw
  274. pop bp
  275. pop ds
  276. end;
  277. end;
  278. *)
  279. begin
  280. if DummyIntRedir=false then
  281. begin
  282. SetIntVec(DummyInt,@CallInt);
  283. DummyIntRedir:=true;
  284. end;
  285. CallAddr:=Proc;
  286. dos.intr(DummyInt,r);
  287. end;
  288. {$endif}
  289. (*const ActiveBlocks: word = 0;*)
  290. function GetDosMem(var M: MemPtr; Size: word): boolean;
  291. var P: pointer;
  292. L: longint;
  293. begin
  294. M.Size:=Size;
  295. {$ifndef DPMI}
  296. GetMem(P,Size);
  297. M.Seg:=PtrRec(P).Seg; M.Ofs:=PtrRec(P).Ofs;
  298. {$else}
  299. L:=GlobalDosAlloc(Size);
  300. M.Seg:=(L shr 16); M.Ofs:=0;
  301. M.Sel:=(L and $ffff);
  302. {$endif}
  303. if M.Seg<>0 then M.Clear;
  304. GetDosMem:=M.Seg<>0;
  305. (* Inc(ActiveBlocks);
  306. write('|DMC:',ActiveBlocks,'-S:',M.Sel,'-S:',M.Seg);*)
  307. end;
  308. procedure FreeDosMem(var M: MemPtr);
  309. begin
  310. if M.Size=0 then Exit;
  311. {$ifndef DPMI}
  312. if M.Seg<>0 then
  313. FreeMem(Ptr(M.Seg,M.Ofs),M.Size);
  314. {$else}
  315. if M.Sel<>0 then
  316. if GlobalDosFree(M.Sel)<>0 then
  317. writeln('!!!Failed to deallocate Dos block!!!');
  318. {$endif}
  319. FillChar(M,SizeOf(M),0);
  320. end;
  321. {$ifdef DPMI}
  322. function GetSelectorForSeg(Seg: word): word;
  323. var Sel: word;
  324. r: registers;
  325. begin
  326. r.ax:=$0002; r.bx:=Seg;
  327. intr(DPMI_Intr,r);
  328. if (r.flags and fCarry)=0 then
  329. Sel:=r.ax
  330. else
  331. Sel:=0;
  332. GetSelectorForSeg:=Sel;
  333. end;
  334. {$endif}
  335. function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
  336. {$ifndef DPMI}
  337. begin
  338. Move(DosPtr^,PMPtr^,Size);
  339. MoveDosToPM:=true;
  340. end;
  341. {$else}
  342. var Sel: word;
  343. OK,DisposeSel: boolean;
  344. begin
  345. Sel:=GetSelectorForSeg(PtrRec(DosPtr).Seg);
  346. OK:=Sel<>0; DisposeSel:=false;
  347. if OK=false then
  348. begin
  349. Sel:=AllocSelector(0);
  350. OK:=Sel<>0;
  351. if OK then
  352. begin
  353. SetSelectorLimit(Sel,PtrRec(DosPtr).Ofs+Size);
  354. OK:=SetSelectorBase(Sel,PtrRec(DosPtr).Seg shl 4)=Sel;
  355. end;
  356. if OK then DisposeSel:=true;
  357. end;
  358. if OK then
  359. begin
  360. Move(ptr(Sel,PtrRec(DosPtr).Ofs)^,PMPtr^,Size);
  361. if DisposeSel then FreeSelector(Sel);
  362. end;
  363. MoveDosToPM:=OK;
  364. end;
  365. {$endif}
  366. function MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
  367. {$ifndef DPMI}
  368. begin
  369. Move(PMPtr^,DosPtr^,Size);
  370. MovePMToDos:=true;
  371. end;
  372. {$else}
  373. var Sel: word;
  374. OK,DisposeSel: boolean;
  375. begin
  376. Sel:=GetSelectorForSeg(PtrRec(DosPtr).Seg);
  377. OK:=Sel<>0; DisposeSel:=false;
  378. if OK=false then
  379. begin
  380. Sel:=AllocSelector(0);
  381. OK:=Sel<>0;
  382. if OK then
  383. begin
  384. SetSelectorLimit(Sel,PtrRec(DosPtr).Ofs+Size);
  385. OK:=SetSelectorBase(Sel,PtrRec(DosPtr).Seg shl 4)=Sel;
  386. end;
  387. if OK then DisposeSel:=true;
  388. end;
  389. if OK then
  390. begin
  391. Move(PMPtr^,ptr(Sel,PtrRec(DosPtr).Ofs)^,Size);
  392. if DisposeSel then FreeSelector(Sel);
  393. end;
  394. MovePMToDos:=OK;
  395. end;
  396. {$endif}
  397. procedure realGetIntVec(IntNo: byte; var P: pointer);
  398. {$ifndef DPMI}
  399. begin
  400. GetIntVec(IntNo,P);
  401. end;
  402. {$else}
  403. var r: registers;
  404. begin
  405. r.ax:=$200; r.bl:=IntNo;
  406. intr(DPMI_Intr,r);
  407. P:=Ptr(r.cx,r.dx);
  408. end;
  409. {$endif}
  410. procedure MemPtr.MoveDataTo(const Src; DSize: word);
  411. begin
  412. if DSize>Size then
  413. RunError(216);
  414. Move(Src,Ptr(DataSeg,DataOfs)^,DSize);
  415. end;
  416. procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
  417. begin
  418. if DSize>Size then
  419. RunError(216);
  420. Move(Ptr(DataSeg,DataOfs)^,Dest,DSize);
  421. end;
  422. procedure MemPtr.Clear;
  423. begin
  424. FillChar(Ptr(DataSeg,DataOfs)^,Size,0);
  425. end;
  426. procedure RealAbstract;
  427. begin
  428. writeln('Abstract call in real mode...');
  429. RunError(255);
  430. end;
  431. function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
  432. {$ifdef DPMI}
  433. var r: registers;
  434. P: pointer;
  435. begin
  436. r.ax:=$0303;
  437. r.ds:=PtrRec(PMAddr).Seg; r.si:=PtrRec(PMAddr).Ofs;
  438. r.es:=PtrRec(RealRegs).Seg; r.di:=PtrRec(RealRegs).Ofs;
  439. intr(DPMI_Intr,r);
  440. if (r.flags and fCarry)=0 then
  441. P:=MakePtr(r.cx,r.dx)
  442. else
  443. P:=nil;
  444. allocrmcallback:=P;
  445. end;
  446. {$else}
  447. begin
  448. RealAbstract;
  449. end;
  450. {$endif}
  451. procedure freermcallback(RealCallAddr: pointer);
  452. {$ifdef DPMI}
  453. var r: registers;
  454. begin
  455. r.ax:=$0304;
  456. r.cx:=PtrRec(RealCallAddr).Seg; r.dx:=PtrRec(RealCallAddr).Seg;
  457. intr(DPMI_Intr,r);
  458. end;
  459. {$else}
  460. begin
  461. RealAbstract;
  462. end;
  463. {$endif}
  464. {$endif TP}
  465. {$ifdef GO32V2}
  466. { --------------------- GO32 --------------------- }
  467. uses go32;
  468. function GetDosMem(var M: MemPtr; Size: word): boolean;
  469. var L: longint;
  470. begin
  471. M.Size:=Size;
  472. L:=global_dos_alloc(Size);
  473. M.Seg:=(L shr 16); M.Ofs:=0;
  474. M.Sel:=(L and $ffff);
  475. GetDosMem:=M.Seg<>0;
  476. end;
  477. procedure FreeDosMem(var M: MemPtr);
  478. begin
  479. if M.Size=0 then Exit;
  480. if M.Sel<>0 then
  481. if global_dos_free(M.Sel)=false then
  482. writeln('!!!Failed to deallocate Dos block!!!');
  483. FillChar(M,SizeOf(M),0);
  484. end;
  485. procedure realintr(IntNo: byte; var r: registers);
  486. var rr: trealregs;
  487. begin
  488. rr.realeax:=r.ax;
  489. rr.realebx:=r.bx;
  490. rr.realecx:=r.cx;
  491. rr.realedx:=r.dx;
  492. rr.realesi:=r.si;
  493. rr.realedi:=r.di;
  494. rr.reales:=r.es;
  495. rr.realds:=r.ds;
  496. go32.realintr(IntNo,rr);
  497. r.ax:=rr.realeax and $ffff;
  498. r.bx:=rr.realebx and $ffff;
  499. r.cx:=rr.realecx and $ffff;
  500. r.dx:=rr.realedx and $ffff;
  501. r.si:=rr.realesi and $ffff;
  502. r.di:=rr.realedi and $ffff;
  503. r.es:=rr.reales and $ffff;
  504. r.ds:=rr.realds and $ffff;
  505. end;
  506. function dorealcall(var regs : trealregs) : boolean;
  507. begin
  508. regs.realsp:=0;
  509. regs.realss:=0;
  510. asm
  511. movw $0x0,%bx
  512. xorl %ecx,%ecx
  513. movl regs,%edi
  514. { es is always equal ds }
  515. movl $0x301,%eax
  516. int $0x31
  517. setnc %al
  518. movb %al,__RESULT
  519. end;
  520. end;
  521. procedure realcall(Proc: pointer; var r: registers);
  522. var rr: trealregs;
  523. begin
  524. rr.realeax:=r.ax;
  525. rr.realebx:=r.bx;
  526. rr.realecx:=r.cx;
  527. rr.realedx:=r.dx;
  528. rr.realesi:=r.si;
  529. rr.realedi:=r.di;
  530. rr.reales:=r.es;
  531. rr.realds:=r.ds;
  532. rr.flags:=r.flags;
  533. rr.CS:=PtrRec(Proc).Seg;
  534. rr.IP:=PtrRec(Proc).Ofs;
  535. rr.realss:=0; rr.realsp:=0;
  536. dorealcall(rr);
  537. r.ax:=rr.realeax and $ffff;
  538. r.bx:=rr.realebx and $ffff;
  539. r.cx:=rr.realecx and $ffff;
  540. r.dx:=rr.realedx and $ffff;
  541. r.si:=rr.realesi and $ffff;
  542. r.di:=rr.realedi and $ffff;
  543. r.es:=rr.reales and $ffff;
  544. r.ds:=rr.realds and $ffff;
  545. r.flags:=rr.Flags and $ffff;
  546. end;
  547. function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
  548. begin
  549. dosmemget(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
  550. MoveDosToPM:=true;
  551. end;
  552. function MovePMToDos(PMPtr, DosPtr: pointer; Size: word): boolean;
  553. begin
  554. dosmemput(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
  555. MovePMToDos:=true;
  556. end;
  557. procedure realGetIntVec(IntNo: byte; var P: pointer);
  558. var si: tseginfo;
  559. begin
  560. get_rm_interrupt(IntNo,si);
  561. PtrRec(P).Seg:=si.segment; PtrRec(P).Ofs:=longint(si.offset);
  562. end;
  563. procedure MemPtr.MoveDataTo(var Src; DSize: word);
  564. begin
  565. dpmi_dosmemput(DosSeg,DosOfs,Src,DSize);
  566. end;
  567. procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
  568. begin
  569. dpmi_dosmemget(DosSeg,DosOfs,Dest,DSize);
  570. end;
  571. procedure MemPtr.Clear;
  572. begin
  573. dpmi_dosmemfillchar(DosSeg,DosOfs,Size,#0);
  574. end;
  575. function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
  576. var s: tseginfo;
  577. P: pointer;
  578. begin
  579. if get_rm_callback(PMAddr,RealRegs^,s) then
  580. P:=MakePtr(s.segment,longint(s.offset))
  581. else
  582. P:=nil;
  583. allocrmcallback:=P;
  584. end;
  585. procedure freermcallback(RealCallAddr: pointer);
  586. var s: tseginfo;
  587. begin
  588. s.segment:=PtrRec(RealCallAddr).seg;
  589. s.offset:=pointer(longint(PtrRec(RealCallAddr).ofs));
  590. free_rm_callback(s);
  591. end;
  592. {$endif GO32V2}
  593. { ---------------------- COMMON ---------------------- }
  594. function MemPtr.DosPtr: pointer;
  595. begin
  596. DosPtr:=MakePtr(Seg,Ofs);
  597. end;
  598. function MemPtr.DataPtr: pointer;
  599. begin
  600. DataPtr:=MakePtr(DataSeg,DataOfs);
  601. end;
  602. function MemPtr.DataSeg: word;
  603. begin
  604. {$ifndef DPMI}
  605. DataSeg:=Seg;
  606. {$else}
  607. DataSeg:=Sel;
  608. {$endif}
  609. end;
  610. function MemPtr.DataOfs: word;
  611. begin
  612. {$ifndef DPMI}
  613. DataOfs:=Ofs;
  614. {$else}
  615. DataOfs:=0;
  616. {$endif}
  617. end;
  618. function MemPtr.DosSeg: word;
  619. begin
  620. DosSeg:=Seg;
  621. end;
  622. function MemPtr.DosOfs: word;
  623. begin
  624. DosOfs:=Ofs;
  625. end;
  626. function MakePtr(ASeg, AOfs: word): pointer;
  627. var P: pointer;
  628. begin
  629. with PtrRec(P) do
  630. begin
  631. Seg:=ASeg; Ofs:=AOfs;
  632. end;
  633. MakePtr:=P;
  634. end;
  635. END.
  636. {
  637. $Log$
  638. Revision 1.3 2002-09-07 15:40:47 peter
  639. * old logs removed and tabs fixed
  640. }