{ >What you *can* do is these things. >1. You can modify the limit of a selector from $0000FFFF to > $xxxxFFFF so assembler code can use 32-bit addressing. > Note that you may not change the lower 16-bit of the limit > field, or else the DPMI server crashes. >2. You can compile a 32-bit assembler procedure into your > program. It just needs a tiny (16 byte) wrapper and must > reside in the low 64K of a segment (or else interrupts > cannot return correctly). However, the BP linker does > not support 32-bit fixups so there are limits as to what > you can put into the assembler code. >3. If you are willing to give up assembler access to BP > variables, then you can make a binary image and link > that into your program. Then you can do whatever pleases > you in the assembler procedure. >If there is interrest, I could post an example routine showing >this. Three files are needed: a batch file for assembly, an assembler file with 32-bit code, and a pascal test program. The test program is not supposed to do anything useful. The code is unsupported. You must know what you're doing. You'll need the `exe2bin' or `exetobin' utility; you'll need BP7 (with Turbo Assembler, and you cannot use TP7). You must be using Borland's DPMI or some DPMI that supports 32-bit programs. Don't even think about running this on a 286. When things go wrong it's not my fault. Don't tell me you know a better way to get the segment limit, because so do I. Morten Welinder terra@diku.dk { THE BATCH FILE } { CUT HERE } {***************************************************************************} @Echo Off Tasm /M2 /T /L Test32 If Not Exist Test32.Obj Goto End Tlink /x test32 >Nul Exe2bin Test32.Exe Test32.Bin Rem Del Test32.Exe Del Test32.Obj :End { THE ASSEMBLER PROGRAM } { CUT HERE } {***************************************************************************} ; --------------------------------------------------------------------------- ; Example 32 bit program for use with Borland Pascal 7.0 ; --------------------------------------------------------------------------- Ideal ; (Keep Tasm happy) P386 Model Use32 Huge,Pascal Segment Code Use32 Assume Cs:Code ; --------------------------------------------------------------------------- Entry0: Movzx Eax,[Word Esp] ; Change the stack frame to 32 bits Shr [Dword Esp],16 ; so [Esp+xxx] works as expected. Push Eax Jmp P0 Align 10h Entry1: Movzx Eax,[Word Esp] ; Aligned 10h for speed. Shr [Dword Esp],16 Push Eax Jmp P1 Align 10h Entry2: Movzx Eax,[Word Esp] ; Aligned 10h for speed. Shr [Dword Esp],16 Push Eax Jmp P2 ; etc. ; --------------------------------------------------------------------------- Align 10h Proc P0 Far L1:Dword,L2:Dword Mov Eax,[L1] ; Add the parameters Add Eax,[L2] Shld Edx,Eax,16 ; Output is left in Dx:Ax Ret Endp ; --------------------------------------------------------------------------- Align 10h Proc P1 Far Push Ds ; Call MsDos from a 32 bit segment Mov Ax,Cs ; Never ever perform a software Mov Ds,Ax ; interrupt if Ip>=64K! Mov Ah,9 Mov Edx,Offset Message Int 21h Pop Ds Ret Message Db 'Hello, 32 bit world!',13,10,'$' Endp ; --------------------------------------------------------------------------- Align 10h Proc P2 Far P:Dword Push Ds Xor Esi,Esi Lds Si,[Small P] Mov Ecx,20000h/4 @@1: Mov [Esi],Esi Add Esi,4 Loop @@1 Pop Ds Ret Endp ; --------------------------------------------------------------------------- Ends End { THE TEST PROGRAM } { CUT HERE } {***************************************************************************} Program Test; { ------------------------------------------------------------------------- } Uses Winapi, Dos; { ------------------------------------------------------------------------- } Const Dpmi_32BitSegment = $4000; Type Dpmi_Descriptor = Record Limit0015 : Word; Base0015 : Word; Base1623 : Byte; Rights : Byte; { 7=Prsnt, 6-5=Dpl, 4=App, } { 3-0=Type } Rights386 : Byte; { 7=Gran, 6=Size32, 5=0, } { 4=Avail, 3-0=Limit1619 } Base2431 : Byte; End; Var Sel : Word; Oldright : Word; ProcPtr : Pointer; P1 : Function(L1,L2: LongInt): LongInt; P2 : Procedure; P3 : Procedure(P: Pointer); Fil : File; Data : Pointer; Dsel : Word; { ------------------------------------------------------------------------- } Procedure Dpmi_SetSelectorLimit(Sel: Word; Limit: LongInt); Assembler; Asm Mov Ax,0008H Mov Bx,[Sel] Mov Dx,[Word Ptr Limit] Mov Cx,[Word Ptr Limit+2] Int 31H End; { ------------------------------------------------------------------------- } Procedure Dpmi_GetDescriptor(Sel: Word; Var Buffer: Dpmi_Descriptor); Assembler; Asm Mov Ax,000Bh Mov Bx,[Sel] Les Di,[Buffer] Int 31H End; { ------------------------------------------------------------------------- } Procedure Dpmi_SetDescriptor(Sel: Word; Var Buffer: Dpmi_Descriptor); Assembler; Asm Mov Ax,000Ch Mov Bx,[Sel] Les Di,[Buffer] Int 31H End; { ------------------------------------------------------------------------- } Function Dpmi_GetAccessRights(Sel: Word): Word; Assembler; Var Buffer : Dpmi_Descriptor; Asm Mov Bx,[Sel] Push Bx Push Ss Lea Di,[Buffer] Push Di Call Dpmi_GetDescriptor Mov Ax,[Word Ptr Buffer+5] End; { ------------------------------------------------------------------------- } Procedure Dpmi_SetAccessRights(Sel: Word; Rights: Word); Assembler; Var Buffer : Dpmi_Descriptor; Asm Mov Bx,[Sel] Lea Di,[Buffer] Push Bx Push Ss Push Di Push Bx Push Ss Push Di Call Dpmi_GetDescriptor Mov Ax,[Word Ptr Buffer+5] And Ax,8F00h Mov Bx,[Rights] And Bx,50Ffh Or Ax,Bx Mov [Word Ptr Buffer+5],Ax Call Dpmi_SetDescriptor End; { ------------------------------------------------------------------------- } Function Dpmi_GetSelectorLimit(Sel: Word): LongInt; Assembler; Var Buffer : Dpmi_Descriptor; Asm Mov Bx,[Sel] Push Bx Push Ss Lea Di,[Buffer] Push Di Call Dpmi_GetDescriptor Mov Dx,[Word Ptr Buffer+6] Mov Ax,[Word Ptr Buffer] Test Dl,80H Je @@3 Mov Bx,Ax Mov Cl,4 Shr Bx,Cl Mov Cl,12 Shl Dx,Cl Shl Ax,Cl Or Dx,Bx Or Ax,0Fffh Jmp @@2 @@3: And Dx,0Fh Jmp @@2 @@1: Mov Ax,0 Mov Dx,0 @@2: End; { ------------------------------------------------------------------------- } Function Int2HexN(L: LongInt; N:Integer): String; Const Digits : Array[0..15] Of Char = '0123456789ABCDEF'; Var S : String; Begin S:=''; While N>0 Do Begin S:=Digits[L And $F]+S; Dec(N); L:=L Shr 4; End; Int2HexN:=S; End; { -------------------------------------------------------------------------- } Begin Data:=GlobalallocPtr(Gmem_Zeroinit,$20000); Dsel:=Seg(Data^); Dpmi_SetSelectorLimit(Dsel,$1FFFF); GetMem(ProcPtr,$4000); Assign(Fil,'Test32.Bin'); Reset(Fil,1); BlockRead(Fil,ProcPtr^,FileSize(Fil)); Close(Fil); LongInt(@P1):=(LongInt(ProcPtr)+0*16); LongInt(@P2):=(LongInt(ProcPtr)+1*16); LongInt(@P3):=(LongInt(ProcPtr)+2*16); Sel:=Seg(ProcPtr^); Oldright:=Dpmi_GetAccessRights(Sel); Dpmi_SetAccessRights(Sel,(Oldright Or Dpmi_32BitSegment) And $FFF1+$A); Writeln('Proc: ',Int2HexN(Sel,4),':',Int2HexN(Ofs(ProcPtr^),8)); Writeln('Base: ',Int2HexN(Getselectorbase(Sel),8)); Writeln('Limit: ',Int2HexN(Dpmi_GetSelectorLimit(Sel),8)); Writeln('Rights: ',Int2HexN(Dpmi_GetAccessRights(Sel),4)); Writeln; Writeln('Data: ',Int2HexN(Seg(Data^),4),':',Int2HexN(Ofs(Data^),8)); Writeln('Base: ',Int2HexN(Getselectorbase(Dsel),8)); Writeln('Limit: ',Int2HexN(Dpmi_GetSelectorLimit(Dsel),8)); Writeln('Rights: ',Int2HexN(Dpmi_GetAccessRights(Dsel),4)); Writeln; Writeln('Ss:Sp: ',Int2HexN(SSeg,4),':',Int2HexN(SPtr,4)); Writeln('Result: ',Int2HexN(P1($12345678,$87654321),8)); P2; P3(Data); Dpmi_SetAccessRights(Sel,Oldright); Dpmi_SetSelectorLimit(Dsel,$FFFF); GlobalfreePtr(Data); End.