2
This file is part of the Free Sockets Interface
3
Copyright (c) 1999 by Berczi Gabor
5
Support routines for DPMI programs
7
See the file COPYING.FCL, included in this distribution,
8
for details about the copyright.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
**********************************************************************}
15
{$ifdef VER70}{$define TP}{$endif}
29
function DosPtr: pointer;
30
function DataPtr: pointer;
31
function DosSeg: word;
32
function DosOfs: word;
33
procedure MoveDataTo(var Src; DSize: word);
34
procedure MoveDataFrom(DSize: word; var Dest);
37
function DataSeg: word;
38
function DataOfs: word;
41
PtrRec = packed record
45
registers32 = packed record { DPMI call structure }
65
pregisters = ^registers;
67
function GetDosMem(var M: MemPtr; Size: word): boolean;
68
procedure FreeDosMem(var M: MemPtr);
69
procedure realintr(IntNo: byte; var r: registers);
70
{procedure realintr32(IntNo: byte; var r: registers32);}
71
procedure realcall(Proc: pointer; var r: registers);
72
function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
73
function MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
74
procedure realGetIntVec(IntNo: byte; var P: pointer);
75
function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
76
procedure freermcallback(RealCallAddr: pointer);
78
function MakePtr(ASeg,AOfs: word): pointer;
83
{$ifdef DPMI}uses WinAPI;{$endif}
90
TDPMIRegisters = {$ifdef TP}Registers32{$else}TRegisters32{$endif};
93
DPMIRegs: TDPMIRegisters;
96
procedure realintr(IntNo: byte; var r: registers);
100
FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
101
DPMIRegs.EAX := r.ax;
102
DPMIRegs.EBX := r.bx;
103
DPMIRegs.ECX := r.cx;
104
DPMIRegs.EDX := r.dx;
105
DPMIRegs.EDI := r.di;
106
DPMIRegs.ESI := r.si;
107
DPMIRegs.EBP := r.bp;
110
DPMIRegs.Flags := r.flags;
115
Regs.ES := Seg(DPMIRegs);
116
Regs.DI := Ofs(DPMIRegs);
117
Intr(DPMI_INTR, Regs);
118
r.ax := DPMIRegs.EAX;
119
r.bx := DPMIRegs.EBX;
120
r.cx := DPMIRegs.ECX;
121
r.dx := DPMIRegs.EDX;
122
r.di := DPMIRegs.EDI;
123
r.si := DPMIRegs.ESI;
124
r.bp := DPMIRegs.EBP;
127
r.Flags := DPMIRegs.Flags;
135
(*procedure realintr32(IntNo: byte; var r: registers32);
139
FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
146
Regs.ES := Seg(DPMIRegs);
147
Regs.DI := Ofs(DPMIRegs);
148
Intr(DPMI_INTR, Regs);
160
const DummyIntRedir: boolean = false;
161
CallAddr: pointer = nil;
163
procedure CallInt; assembler;
170
mov ax, ds:CallAddr.word[0]
171
mov cs:@JmpAddr.word[0], ax
172
mov ax, ds:CallAddr.word[2]
173
mov cs:@JmpAddr.word[2], ax
186
mov word ptr cs:@regax, ax
191
mov word ptr ss:[bx+6], ax
193
mov ax, word ptr cs:@regax
199
procedure realcall(Proc: pointer; var r: registers);
203
FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
204
DPMIRegs.EAX := r.ax;
205
DPMIRegs.EBX := r.bx;
206
DPMIRegs.ECX := r.cx;
207
DPMIRegs.EDX := r.dx;
208
DPMIRegs.EDI := r.di;
209
DPMIRegs.ESI := r.si;
210
DPMIRegs.EBP := r.bp;
213
DPMIRegs.Flags := r.flags;
214
DPMIRegs.CS := PtrRec(Proc).Seg;
215
DPMIRegs.IP := PtrRec(Proc).Ofs;
216
DPMIRegs.SS :=0; DPMIRegs.SP:=0;
220
Regs.ES := Seg(DPMIRegs);
221
Regs.DI := Ofs(DPMIRegs);
222
Intr(DPMI_INTR, Regs);
223
r.ax := DPMIRegs.EAX and $ffff;
224
r.bx := DPMIRegs.EBX and $ffff;
225
r.cx := DPMIRegs.ECX and $ffff;
226
r.dx := DPMIRegs.EDX and $ffff;
227
r.di := DPMIRegs.EDI and $ffff;
228
r.si := DPMIRegs.ESI and $ffff;
229
r.bp := DPMIRegs.EBP and $ffff;
232
r.Flags := DPMIRegs.Flags and $ffff;
242
mov cs:@Call+1.word, bx
243
mov cs:@Call+3.word, ax
246
mov @rptr.word[2], ds
247
mov @rptr.word[0], si
287
mov es, @rptr.word[2]
288
mov di, @rptr.word[0]
315
if DummyIntRedir=false then
317
SetIntVec(DummyInt,@CallInt);
321
dos.intr(DummyInt,r);
326
(*const ActiveBlocks: word = 0;*)
328
function GetDosMem(var M: MemPtr; Size: word): boolean;
335
M.Seg:=PtrRec(P).Seg; M.Ofs:=PtrRec(P).Ofs;
337
L:=GlobalDosAlloc(Size);
338
M.Seg:=(L shr 16); M.Ofs:=0;
339
M.Sel:=(L and $ffff);
341
if M.Seg<>0 then M.Clear;
343
(* Inc(ActiveBlocks);
344
write('|DMC:',ActiveBlocks,'-S:',M.Sel,'-S:',M.Seg);*)
347
procedure FreeDosMem(var M: MemPtr);
349
if M.Size=0 then Exit;
352
FreeMem(Ptr(M.Seg,M.Ofs),M.Size);
355
if GlobalDosFree(M.Sel)<>0 then
356
writeln('!!!Failed to deallocate Dos block!!!');
359
FillChar(M,SizeOf(M),0);
363
function GetSelectorForSeg(Seg: word): word;
367
r.ax:=$0002; r.bx:=Seg;
369
if (r.flags and fCarry)=0 then
373
GetSelectorForSeg:=Sel;
377
function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
380
Move(DosPtr^,PMPtr^,Size);
385
OK,DisposeSel: boolean;
387
Sel:=GetSelectorForSeg(PtrRec(DosPtr).Seg);
388
OK:=Sel<>0; DisposeSel:=false;
391
Sel:=AllocSelector(0);
395
SetSelectorLimit(Sel,PtrRec(DosPtr).Ofs+Size);
396
OK:=SetSelectorBase(Sel,PtrRec(DosPtr).Seg shl 4)=Sel;
398
if OK then DisposeSel:=true;
402
Move(ptr(Sel,PtrRec(DosPtr).Ofs)^,PMPtr^,Size);
403
if DisposeSel then FreeSelector(Sel);
409
function MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
412
Move(PMPtr^,DosPtr^,Size);
417
OK,DisposeSel: boolean;
419
Sel:=GetSelectorForSeg(PtrRec(DosPtr).Seg);
420
OK:=Sel<>0; DisposeSel:=false;
423
Sel:=AllocSelector(0);
427
SetSelectorLimit(Sel,PtrRec(DosPtr).Ofs+Size);
428
OK:=SetSelectorBase(Sel,PtrRec(DosPtr).Seg shl 4)=Sel;
430
if OK then DisposeSel:=true;
434
Move(PMPtr^,ptr(Sel,PtrRec(DosPtr).Ofs)^,Size);
435
if DisposeSel then FreeSelector(Sel);
441
procedure realGetIntVec(IntNo: byte; var P: pointer);
449
r.ax:=$200; r.bl:=IntNo;
455
procedure MemPtr.MoveDataTo(const Src; DSize: word);
459
Move(Src,Ptr(DataSeg,DataOfs)^,DSize);
462
procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
466
Move(Ptr(DataSeg,DataOfs)^,Dest,DSize);
469
procedure MemPtr.Clear;
471
FillChar(Ptr(DataSeg,DataOfs)^,Size,0);
474
procedure RealAbstract;
476
writeln('Abstract call in real mode...');
480
function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
486
r.ds:=PtrRec(PMAddr).Seg; r.si:=PtrRec(PMAddr).Ofs;
487
r.es:=PtrRec(RealRegs).Seg; r.di:=PtrRec(RealRegs).Ofs;
489
if (r.flags and fCarry)=0 then
490
P:=MakePtr(r.cx,r.dx)
501
procedure freermcallback(RealCallAddr: pointer);
506
r.cx:=PtrRec(RealCallAddr).Seg; r.dx:=PtrRec(RealCallAddr).Seg;
519
{ --------------------- GO32 --------------------- }
523
function GetDosMem(var M: MemPtr; Size: word): boolean;
527
L:=global_dos_alloc(Size);
528
M.Seg:=(L shr 16); M.Ofs:=0;
529
M.Sel:=(L and $ffff);
533
procedure FreeDosMem(var M: MemPtr);
535
if M.Size=0 then Exit;
537
if global_dos_free(M.Sel)=false then
538
writeln('!!!Failed to deallocate Dos block!!!');
539
FillChar(M,SizeOf(M),0);
542
procedure realintr(IntNo: byte; var r: registers);
553
go32.realintr(IntNo,rr);
554
r.ax:=rr.realeax and $ffff;
555
r.bx:=rr.realebx and $ffff;
556
r.cx:=rr.realecx and $ffff;
557
r.dx:=rr.realedx and $ffff;
558
r.si:=rr.realesi and $ffff;
559
r.di:=rr.realedi and $ffff;
560
r.es:=rr.reales and $ffff;
561
r.ds:=rr.realds and $ffff;
564
function dorealcall(var regs : trealregs) : boolean;
572
{ es is always equal ds }
581
procedure realcall(Proc: pointer; var r: registers);
593
rr.CS:=PtrRec(Proc).Seg;
594
rr.IP:=PtrRec(Proc).Ofs;
596
rr.realss:=0; rr.realsp:=0;
600
r.ax:=rr.realeax and $ffff;
601
r.bx:=rr.realebx and $ffff;
602
r.cx:=rr.realecx and $ffff;
603
r.dx:=rr.realedx and $ffff;
604
r.si:=rr.realesi and $ffff;
605
r.di:=rr.realedi and $ffff;
606
r.es:=rr.reales and $ffff;
607
r.ds:=rr.realds and $ffff;
608
r.flags:=rr.Flags and $ffff;
611
function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
613
dosmemget(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
617
function MovePMToDos(PMPtr, DosPtr: pointer; Size: word): boolean;
619
dosmemput(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
623
procedure realGetIntVec(IntNo: byte; var P: pointer);
626
get_rm_interrupt(IntNo,si);
627
PtrRec(P).Seg:=si.segment; PtrRec(P).Ofs:=longint(si.offset);
630
procedure MemPtr.MoveDataTo(var Src; DSize: word);
632
dpmi_dosmemput(DosSeg,DosOfs,Src,DSize);
635
procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
637
dpmi_dosmemget(DosSeg,DosOfs,Dest,DSize);
640
procedure MemPtr.Clear;
642
dpmi_dosmemfillchar(DosSeg,DosOfs,Size,#0);
646
function allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
650
if get_rm_callback(PMAddr,RealRegs^,s) then
651
P:=MakePtr(s.segment,longint(s.offset))
657
procedure freermcallback(RealCallAddr: pointer);
660
s.segment:=PtrRec(RealCallAddr).seg;
661
s.offset:=pointer(longint(PtrRec(RealCallAddr).ofs));
667
{ ---------------------- COMMON ---------------------- }
669
function MemPtr.DosPtr: pointer;
671
DosPtr:=MakePtr(Seg,Ofs);
674
function MemPtr.DataPtr: pointer;
676
DataPtr:=MakePtr(DataSeg,DataOfs);
679
function MemPtr.DataSeg: word;
688
function MemPtr.DataOfs: word;
697
function MemPtr.DosSeg: word;
702
function MemPtr.DosOfs: word;
707
function MakePtr(ASeg, AOfs: word): pointer;
712
Seg:=ASeg; Ofs:=AOfs;