Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

Need help with DPMI function 301h (Developers)

posted by Laaca(R) Homepage, Czech republic, 12.08.2019, 22:19

Hello all!
I need your help with my routine using DPMI function 301h. In my task I want to talk with legacy (non-ACPI) PnP BIOS interface.
I want it to be compilable with TurboPascal-realmode and Freepascal-32bitPM.
The original code is quite bit but I simplified the code to be as small as possible and to use rather assembler that pascal.
In my code I call the PNP-BIOS function 00h - GetNumber_and_size_of_PNP_nodes
(for reference please see specification - relevant pages 26-31)

THIS REALMODE CODE WORKS PERFECT:
(Note: in line "InternalCallPNP($F000,24114,$F000,p1,p2);" just change the magic numbers for numbers you get from scan of your machine - see the 3rd snipet of code)

Program TestPNP;

Procedure InternalCallPNP(seg_entry,offs_entry,ds_seg:word;var param1,param2:word);
var p:pointer;
begin
asm
mov ax,ds_seg
push ax

push $b800 {for simplicity we will not mess with transfer buffers stuff}
push 0 {but we just use some safe realmode address like videobuffer}
push $b800
push 2

push 0

mov ax,offs_entry
mov bx,seg_entry

mov p.word[0],ax
mov p.word[2],bx

call p

pop ax
pop ax
pop ax
pop ax
pop ax
pop ax
end;

param1:=MemW[$B800:0];
param2:=MemW[$B800:2];
end;

var p1,p2:word;
begin
InternalCallPNP($F000,24114,$F000,p1,p2);
writeln('p1: ',p1);
writeln('p2: ',p2);
end.



BUT IN THE CODE BELOW IS THE PROBLEM - this code should be analogical to previous one but works in 32-bit protected mode using Freepascal.
I can not just call the realmode BIOS entrypoint from protected mode so I have to use the emulation via DPMI function 301h. But it does not work at all. In FreeDOS the computer freezes after instruction INT31h and in Windows98 freezes the task.

Program TestPNP;
uses Go32;

Procedure InternalCallPNP(seg_entry,offs_entry,ds_seg:word;var param1,param2:word);
var r:TRealRegs;
begin

FillChar(r,sizeof(TRealRegs),0);
r.cs:=seg_entry;
r.ip:=offs_entry;

asm
mov ax,ds_seg
push ax

push $b800 {for simplicity we will not mess with transfer buffers stuff}
push 0 {but we just use some safe realmode address like videobuffer}
push $b800
push 2

push 0

mov edi,r
mov ebx,0
mov ecx,6
mov eax,301h;
int 31h

pop ax
pop ax
pop ax
pop ax
pop ax
pop ax
end;

param1:=MemW[$B800:0];
param2:=MemW[$B800:2];
end;

var p1,p2:word;
begin
InternalCallPNP($F000,24114,$F000,p1,p2);
writeln('p1: ',p1);
writeln('p2: ',p2);
end.



AND THE LAST PIECE OF CODE - the detection of the PNP BIOS and detection of the entrypoint.
This code works in both Turbopascal and Freepascal. (no problem here)

Function RMString(segm,offs:word;len:byte):string;
var a:longint;
s:string;
begin
s:='';
for a:=0 to len-1 do s:=s+char(Mem[segm:offs+a]);
RMstring:=s;
end;


Function ScanSegment(segm:word;var offs:longint;limit:word;gran:word;const SearchStr:string):boolean;
var l:byte;
begin
l:=Length(SearchStr);
repeat
if RMstring(segm,offs,l)=SearchStr then
begin
ScanSegment:=true;
Exit;
end;
inc(offs,gran);
until offs>limit-gran;
offs:=0;
ScanSegment:=false;
end;


Function Get_PNP_BIOS_Entry_Info(var seg_entry,offs_entry,ds_seg:word):boolean;
var scan_seg:word;
scan_ofs:longint;
begin

scan_seg:=$F000;
scan_ofs:=0;

if not ScanSegment(scan_seg,scan_ofs,$FFFF,16,'$PnP')
then begin
seg_entry:=0;
offs_entry:=0;
ds_seg:=0;
Get_PNP_BIOS_Entry_Info:=false;
end
else begin
ds_seg:=MemW[scan_seg:scan_ofs+27];
offs_entry:=MemW[scan_seg:scan_ofs+13];
seg_entry:=MemW[scan_seg:scan_ofs+15];
Get_PNP_BIOS_Entry_Info:=true;
end;
end;

var s,o,d:word;
begin
if not Get_PNP_BIOS_Entry_Info(s,o,d)
then writeln('No PNP BIOS found!')
else begin
writeln('PNP BIOS found!');
writeln('Entrypoint segment: ',s);
writeln('Entrypoint offset: ',o);
writeln('DS register for routine: ',d);
end;
end.

---
DOS-u-akbar!

 

Complete thread:

Back to the forum
Board view  Mix view
15889 Postings in 1469 Threads, 269 registered users, 90 users online (0 registered, 90 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum