1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360 |
- {
- This file is part of the Free Pascal run time library.
- and implements some stuff for protected mode programming
- Copyright (c) 1999-2000 by the Free Pascal development team.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit go32;
- {$S-,R-,I-,Q-} {no stack check, used by DPMIEXCP !! }
- {$inline ON}
- interface
- const
- { contants for the run modes returned by get_run_mode }
- rm_unknown = 0;
- rm_raw = 1; { raw (without HIMEM) }
- rm_xms = 2; { XMS (for example with HIMEM, without EMM386) }
- rm_vcpi = 3; { VCPI (for example HIMEM and EMM386) }
- rm_dpmi = 4; { DPMI (for example DOS box or 386Max) }
- { flags }
- carryflag = $001;
- parityflag = $004;
- auxcarryflag = $010;
- zeroflag = $040;
- signflag = $080;
- trapflag = $100;
- interruptflag = $200;
- directionflag = $400;
- overflowflag = $800;
- type
- tmeminfo = record
- available_memory,
- available_pages,
- available_lockable_pages,
- linear_space,
- unlocked_pages,
- available_physical_pages,
- total_physical_pages,
- free_linear_space,
- max_pages_in_paging_file,
- reserved0,
- reserved1,
- reserved2 : longint;
- end;
- tseginfo = record
- offset : pointer;
- segment : word;
- end;
- trealregs = record
- case integer of
- 1: { 32-bit } (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: longint;
- Flags, ES, DS, FS, GS, IP, CS, SP, SS: word);
- 2: { 16-bit } (DI, DI2, SI, SI2, BP, BP2, R1, R2: word;
- BX, BX2, DX, DX2, CX, CX2, AX, AX2: word);
- 3: { 8-bit } (stuff: array[1..4] of longint;
- BL, BH, BL2, BH2, DL, DH, DL2, DH2,
- CL, CH, CL2, CH2, AL, AH, AL2, AH2: byte);
- 4: { Compat } (RealEDI, RealESI, RealEBP, RealRES,
- RealEBX, RealEDX, RealECX, RealEAX: longint;
- RealFlags,
- RealES, RealDS, RealFS, RealGS,
- RealIP, RealCS, RealSP, RealSS: word);
- end;
- registers = trealregs;
- tdpmiversioninfo = record
- major, minor: byte;
- flags: word;
- cpu: byte;
- master_pic, slave_pic: byte;
- end;
- { this works only with real DPMI }
- function allocate_ldt_descriptors(count : word) : word;
- function free_ldt_descriptor(d : word) : boolean;
- function segment_to_descriptor(seg : word) : word;
- function get_next_selector_increment_value : word;
- function get_segment_base_address(d : word) : dword;
- function set_segment_base_address(d : word;s : dword) : boolean;
- function set_segment_limit(d : word;s : dword): boolean;
- function set_descriptor_access_right(d : word;w : word) : boolean;
- function create_code_segment_alias_descriptor(seg : word) : word;
- function get_linear_addr(phys_addr : dword;size : longint) : dword;
- function free_linear_addr_mapping(linear_addr: dword): boolean;
- function get_segment_limit(d : word) : dword;
- function get_descriptor_access_right(d : word) : longint;
- function get_page_size:longint;
- function map_device_in_memory_block(handle,offset,pagecount,device:dword):boolean;
- function get_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
- function set_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
- function realintr(intnr : word;var regs : trealregs) : boolean;
- function get_dpmi_version(var version: tdpmiversioninfo): boolean;
- { is needed for functions which need a real mode buffer }
- function global_dos_alloc(bytes : longint) : longint;
- function global_dos_free(selector : word) : boolean;
- var
- { selector for the DOS memory (only usable if in DPMI mode) }
- dosmemselector : word;
- { result of dpmi call }
- int31error : word;
- { this procedure copies data where the source and destination }
- { are specified by 48 bit pointers }
- { Note: the procedure checks only for overlapping if }
- { source selector=destination selector }
- procedure seg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
- { fills a memory area specified by a 48 bit pointer with c }
- procedure seg_fillchar(seg : word;ofs : longint;count : longint;c : char);
- procedure seg_fillword(seg : word;ofs : longint;count : longint;w : word);
- {************************************}
- { this works with all PM interfaces: }
- {************************************}
- function get_meminfo(var meminfo : tmeminfo) : boolean;
- function get_pm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
- function set_pm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
- function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
- function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
- function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
- function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
- function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
- function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
- function free_rm_callback(var intaddr : tseginfo) : boolean;
- function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
- function get_cs : word;
- function get_ds : word;
- function get_ss : word;
- { locking functions }
- function allocate_memory_block(size:longint):longint;
- function free_memory_block(blockhandle : longint) : boolean;
- function request_linear_region(linearaddr, size : longint;
- var blockhandle : longint) : boolean;
- function lock_linear_region(linearaddr, size : longint) : boolean;
- function lock_data(var data;size : longint) : boolean;
- function lock_code(functionaddr : pointer;size : longint) : boolean;
- function unlock_linear_region(linearaddr, size : longint) : boolean;
- function unlock_data(var data;size : longint) : boolean;
- function unlock_code(functionaddr : pointer;size : longint) : boolean;
- {$ifdef VER3_0}
- { disables and enables interrupts }
- procedure disable;
- procedure enable;
- function inportb(port : word) : byte;
- function inportw(port : word) : word;
- function inportl(port : word) : longint;
- procedure outportb(port : word;data : byte);
- procedure outportw(port : word;data : word);
- procedure outportl(port : word;data : longint);
- {$else VER3_0}
- { disables and enables interrupts }
- procedure disable;inline;
- procedure enable;inline;
- function inportb(port : word) : byte;inline;
- function inportw(port : word) : word;inline;
- function inportl(port : word) : longint;inline;
- procedure outportb(port : word;data : byte);inline;
- procedure outportw(port : word;data : word);inline;
- procedure outportl(port : word;data : longint);inline;
- {$endif VER3_0}
- function get_run_mode : word;
- function transfer_buffer : longint;
- function tb_segment : longint;
- function tb_offset : longint;
- function tb_size : longint;
- procedure copytodos(var addr; len : longint);
- procedure copyfromdos(var addr; len : longint);
- procedure dpmi_dosmemput(seg : word;ofs : word;var data;count : longint);
- procedure dpmi_dosmemget(seg : word;ofs : word;var data;count : longint);
- procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs : word;count : longint);
- procedure dpmi_dosmemfillchar(seg,ofs : word;count : longint;c : char);
- procedure dpmi_dosmemfillword(seg,ofs : word;count : longint;w : word);
- const
- { this procedures are assigned to the procedure which are needed }
- { for the current mode to access DOS memory }
- { It's strongly recommended to use this procedures! }
- dosmemput : procedure(seg : word;ofs : word;var data;count : longint)=@dpmi_dosmemput;
- dosmemget : procedure(seg : word;ofs : word;var data;count : longint)=@dpmi_dosmemget;
- dosmemmove : procedure(sseg,sofs,dseg,dofs : word;count : longint)=@dpmi_dosmemmove;
- dosmemfillchar : procedure(seg,ofs : word;count : longint;c : char)=@dpmi_dosmemfillchar;
- dosmemfillword : procedure(seg,ofs : word;count : longint;w : word)=@dpmi_dosmemfillword;
- implementation
- {$asmmode ATT}
- { the following procedures copy from and to DOS memory using DPMI }
- procedure dpmi_dosmemput(seg : word;ofs : word;var data;count : longint);
- begin
- seg_move(get_ds,longint(@data),dosmemselector,seg*16+ofs,count);
- end;
- procedure dpmi_dosmemget(seg : word;ofs : word;var data;count : longint);
- begin
- seg_move(dosmemselector,seg*16+ofs,get_ds,longint(@data),count);
- end;
- procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs : word;count : longint);
- begin
- seg_move(dosmemselector,sseg*16+sofs,dosmemselector,dseg*16+dofs,count);
- end;
- procedure dpmi_dosmemfillchar(seg,ofs : word;count : longint;c : char);
- begin
- seg_fillchar(dosmemselector,seg*16+ofs,count,c);
- end;
- procedure dpmi_dosmemfillword(seg,ofs : word;count : longint;w : word);
- begin
- seg_fillword(dosmemselector,seg*16+ofs,count,w);
- end;
- procedure test_int31(flag : longint); stdcall; { stack-args! }
- begin
- asm
- pushl %ebx
- movw $0,INT31ERROR
- movl flag,%ebx
- testb $1,%bl
- jz .Lti31_1
- movw %ax,INT31ERROR
- xorl %eax,%eax
- jmp .Lti31_2
- .Lti31_1:
- movl $1,%eax
- .Lti31_2:
- popl %ebx
- end;
- end;
- function global_dos_alloc(bytes : longint) : longint;
- begin
- asm
- pushl %ebx
- movl bytes,%ebx
- addl $0xf,%ebx // round up
- shrl $0x4,%ebx // convert to Paragraphs
- movl $0x100,%eax // function 0x100
- int $0x31
- jnc .LDos_OK
- movw %ax,INT31ERROR
- xorl %eax,%eax
- jmp .LDos_end
- .LDos_OK:
- shll $0x10,%eax // return Segment in hi(Result)
- movw %dx,%ax // return Selector in lo(Result)
- .LDos_end:
- movl %eax,__result
- popl %ebx
- end;
- end;
- function global_dos_free(selector : word) : boolean;
- begin
- asm
- movw Selector,%dx
- movl $0x101,%eax
- int $0x31
- setnc %al
- movb %al,__RESULT
- end;
- end;
- function realintr(intnr : word;var regs : trealregs) : boolean;
- begin
- regs.realsp:=0;
- regs.realss:=0;
- regs.realres:=0; { play it safe }
- asm
- { save all used registers to avoid crash under NTVDM }
- { when spawning a 32-bit DPMI application }
- pushl %edi
- pushl %ebx
- pushw %fs
- movw intnr,%bx
- xorl %ecx,%ecx
- movl regs,%edi
- { es is always equal ds }
- movl $0x300,%eax
- int $0x31
- popw %fs
- setnc %al
- movb %al,__RESULT
- popl %ebx
- popl %edi
- end;
- end;
- procedure seg_fillchar(seg : word;ofs : longint;count : longint;c : char);
- begin
- asm
- pushl %edi
- movl ofs,%edi
- movl count,%ecx
- movb c,%dl
- { load es with selector }
- pushw %es
- movw seg,%ax
- movw %ax,%es
- { fill eax with duplicated c }
- { so we can use stosl }
- movb %dl,%dh
- movw %dx,%ax
- shll $16,%eax
- movw %dx,%ax
- movl %ecx,%edx
- shrl $2,%ecx
- cld
- rep
- stosl
- movl %edx,%ecx
- andl $3,%ecx
- rep
- stosb
- popw %es
- popl %edi
- end;
- end;
- procedure seg_fillword(seg : word;ofs : longint;count : longint;w : word);
- begin
- asm
- pushl %edi
- movl ofs,%edi
- movl count,%ecx
- movw w,%dx
- { load segment }
- pushw %es
- movw seg,%ax
- movw %ax,%es
- { fill eax }
- movw %dx,%ax
- shll $16,%eax
- movw %dx,%ax
- movl %ecx,%edx
- shrl $1,%ecx
- cld
- rep
- stosl
- movl %edx,%ecx
- andl $1,%ecx
- rep
- stosw
- popw %es
- popl %edi
- end;
- end;
- procedure seg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
- begin
- if count=0 then
- exit;
- if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
- asm
- pushl %esi
- pushl %edi
- pushw %es
- pushw %ds
- cld
- movl count,%ecx
- movl source,%esi
- movl dest,%edi
- movw dseg,%ax
- movw %ax,%es
- movw sseg,%ax
- movw %ax,%ds
- movl %ecx,%eax
- shrl $2,%ecx
- rep
- movsl
- movl %eax,%ecx
- andl $3,%ecx
- rep
- movsb
- popw %ds
- popw %es
- popl %edi
- popl %esi
- end ['ECX','EAX']
- else if (source<dest) then
- { copy backward for overlapping }
- asm
- pushl %esi
- pushl %edi
- pushw %es
- pushw %ds
- std
- movl count,%ecx
- movl source,%esi
- movl dest,%edi
- movw dseg,%ax
- movw %ax,%es
- movw sseg,%ax
- movw %ax,%ds
- addl %ecx,%esi
- addl %ecx,%edi
- movl %ecx,%eax
- andl $3,%ecx
- orl %ecx,%ecx
- jz .LSEG_MOVE1
- { calculate esi and edi}
- decl %esi
- decl %edi
- rep
- movsb
- incl %esi
- incl %edi
- .LSEG_MOVE1:
- subl $4,%esi
- subl $4,%edi
- movl %eax,%ecx
- shrl $2,%ecx
- rep
- movsl
- cld
- popw %ds
- popw %es
- popl %edi
- popl %esi
- end ['ECX','EAX'];
- end;
- {$ifdef VER3_0}
- procedure outportb(port : word;data : byte);
- begin
- asm
- movw port,%dx
- movb data,%al
- outb %al,%dx
- end ['EAX','EDX'];
- end;
- procedure outportw(port : word;data : word);
- begin
- asm
- movw port,%dx
- movw data,%ax
- outw %ax,%dx
- end ['EAX','EDX'];
- end;
- procedure outportl(port : word;data : longint);
- begin
- asm
- movw port,%dx
- movl data,%eax
- outl %eax,%dx
- end ['EAX','EDX'];
- end;
- function inportb(port : word) : byte;
- begin
- asm
- movw port,%dx
- inb %dx,%al
- movb %al,__RESULT
- end ['EAX','EDX'];
- end;
- function inportw(port : word) : word;
- begin
- asm
- movw port,%dx
- inw %dx,%ax
- movw %ax,__RESULT
- end ['EAX','EDX'];
- end;
- function inportl(port : word) : longint;
- begin
- asm
- movw port,%dx
- inl %dx,%eax
- movl %eax,__RESULT
- end ['EAX','EDX'];
- end;
- {$else VER3_0}
- procedure outportb(port : word;data : byte);inline;
- begin
- fpc_x86_outportb(port,data);
- end;
- procedure outportw(port : word;data : word);inline;
- begin
- fpc_x86_outportw(port,data);
- end;
- procedure outportl(port : word;data : longint);inline;
- begin
- fpc_x86_outportl(port,data);
- end;
- function inportb(port : word) : byte;inline;
- begin
- inportb:=fpc_x86_inportb(port);
- end;
- function inportw(port : word) : word;inline;
- begin
- inportw:=fpc_x86_inportw(port);
- end;
- function inportl(port : word) : longint;inline;
- begin
- inportl:=fpc_x86_inportl(port);
- end;
- {$endif VER3_0}
- function get_cs : word;assembler;
- asm
- movw %cs,%ax
- end;
- function get_ss : word;assembler;
- asm
- movw %ss,%ax
- end;
- function get_ds : word;assembler;
- asm
- movw %ds,%ax
- end;
- function set_pm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl intaddr,%eax
- movl (%eax),%edx
- movw 4(%eax),%cx
- movl $0x205,%eax
- movb vector,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl intaddr,%eax
- movw (%eax),%dx
- movw 4(%eax),%cx
- movl $0x201,%eax
- movb vector,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl intaddr,%eax
- movl (%eax),%edx
- movw 4(%eax),%cx
- movl $0x212,%eax
- movb e,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl intaddr,%eax
- movl (%eax),%edx
- movw 4(%eax),%cx
- movl $0x203,%eax
- movb e,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl $0x210,%eax
- movb e,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- movl intaddr,%eax
- movl %edx,(%eax)
- movw %cx,4(%eax)
- popl %ebx
- end;
- end;
- function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movl $0x202,%eax
- movb e,%bl
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- movl intaddr,%eax
- movl %edx,(%eax)
- movw %cx,4(%eax)
- popl %ebx
- end;
- end;
- function get_pm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movb vector,%bl
- movl $0x204,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- movl intaddr,%eax
- movl %edx,(%eax)
- movw %cx,4(%eax)
- popl %ebx
- end;
- end;
- function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
- begin
- asm
- pushl %ebx
- movb vector,%bl
- movl $0x200,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- movl intaddr,%eax
- movzwl %dx,%edx
- movl %edx,(%eax)
- movw %cx,4(%eax)
- popl %ebx
- end;
- end;
- function free_rm_callback(var intaddr : tseginfo) : boolean;
- begin
- asm
- movl intaddr,%eax
- movw (%eax),%dx
- movw 4(%eax),%cx
- movl $0x304,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- end;
- end;
- { here we must use ___v2prt0_ds_alias instead of from v2prt0.s
- because the exception processor sets the ds limit to $fff
- at hardware exceptions }
- var
- ___v2prt0_ds_alias : word; external name '___v2prt0_ds_alias';
- function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
- begin
- asm
- pushl %esi
- pushl %edi
- movl pm_func,%esi
- movl reg,%edi
- pushw %es
- movw ___v2prt0_ds_alias,%ax
- movw %ax,%es
- pushw %ds
- movw %cs,%ax
- movw %ax,%ds
- movl $0x303,%eax
- int $0x31
- popw %ds
- popw %es
- pushf
- call test_int31
- movb %al,__RESULT
- movl rmcb,%eax
- movzwl %dx,%edx
- movl %edx,(%eax)
- movw %cx,4(%eax)
- popl %edi
- popl %esi
- end;
- end;
- function allocate_ldt_descriptors(count : word) : word;
- begin
- asm
- movw count,%cx
- xorl %eax,%eax
- int $0x31
- movw %ax,__RESULT
- end;
- end;
- function free_ldt_descriptor(d : word) : boolean;
- begin
- asm
- pushl %ebx
- movw d,%bx
- movl $1,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function segment_to_descriptor(seg : word) : word;
- begin
- asm
- pushl %ebx
- movw seg,%bx
- movl $2,%eax
- int $0x31
- movw %ax,__RESULT
- popl %ebx
- end;
- end;
- function get_next_selector_increment_value : word;
- begin
- asm
- movl $3,%eax
- int $0x31
- movw %ax,__RESULT
- end;
- end;
- function get_segment_base_address(d : word) : dword;
- begin
- asm
- pushl %ebx
- movw d,%bx
- movl $6,%eax
- int $0x31
- xorl %eax,%eax
- movw %dx,%ax
- shll $16,%ecx
- orl %ecx,%eax
- movl %eax,__RESULT
- popl %ebx
- end;
- end;
- function get_page_size:longint;
- begin
- asm
- pushl %ebx
- movl $0x604,%eax
- int $0x31
- shll $16,%ebx
- movw %cx,%bx
- movl %ebx,__RESULT
- popl %ebx
- end;
- end;
- function request_linear_region(linearaddr, size : longint;
- var blockhandle : longint) : boolean;
- var
- pageofs : longint;
- begin
- pageofs:=linearaddr and $3ff;
- linearaddr:=linearaddr-pageofs;
- size:=size+pageofs;
- asm
- pushl %ebx
- pushl %esi
- movl $0x504,%eax
- movl linearaddr,%ebx
- movl size,%ecx
- movl $1,%edx
- xorl %esi,%esi
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- movl blockhandle,%eax
- movl %esi,(%eax)
- movl %ebx,pageofs
- popl %esi
- popl %ebx
- end;
- if pageofs<>linearaddr then
- request_linear_region:=false;
- end;
- function allocate_memory_block(size:longint):longint;
- begin
- asm
- pushl %ebx
- pushl %esi
- movl $0x501,%eax
- movl size,%ecx
- movl %ecx,%ebx
- shrl $16,%ebx
- andl $65535,%ecx
- int $0x31
- jnc .Lallocate_mem_block_err
- xorl %ebx,%ebx
- xorl %ecx,%ecx
- .Lallocate_mem_block_err:
- shll $16,%ebx
- movw %cx,%bx
- shll $16,%esi
- movw %di,%si
- movl %ebx,__RESULT
- popl %esi
- popl %ebx
- end;
- end;
- function free_memory_block(blockhandle : longint) : boolean;
- begin
- asm
- pushl %edi
- pushl %esi
- movl blockhandle,%esi
- movl %esi,%edi
- shll $16,%esi
- movl $0x502,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %esi
- popl %edi
- end;
- end;
- function lock_linear_region(linearaddr, size : longint) : boolean;
- begin
- asm
- pushl %ebx
- pushl %edi
- pushl %esi
- movl $0x600,%eax
- movl linearaddr,%ecx
- movl %ecx,%ebx
- shrl $16,%ebx
- movl size,%esi
- movl %esi,%edi
- shrl $16,%esi
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %esi
- popl %edi
- popl %ebx
- end;
- end;
- function lock_data(var data;size : longint) : boolean;
- var
- linearaddr : dword;
- begin
- if get_run_mode<>rm_dpmi then
- exit;
- linearaddr:=dword(@data)+get_segment_base_address(get_ds);
- lock_data:=lock_linear_region(linearaddr,size);
- end;
- function lock_code(functionaddr : pointer;size : longint) : boolean;
- var
- linearaddr : dword;
- begin
- if get_run_mode<>rm_dpmi then
- exit;
- linearaddr:=dword(functionaddr)+get_segment_base_address(get_cs);
- lock_code:=lock_linear_region(linearaddr,size);
- end;
- function unlock_linear_region(linearaddr,size : longint) : boolean;
- begin
- asm
- pushl %ebx
- pushl %edi
- pushl %esi
- movl $0x601,%eax
- movl linearaddr,%ecx
- movl %ecx,%ebx
- shrl $16,%ebx
- movl size,%esi
- movl %esi,%edi
- shrl $16,%esi
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %esi
- popl %edi
- popl %ebx
- end;
- end;
- function unlock_data(var data;size : longint) : boolean;
- var
- linearaddr : dword;
- begin
- if get_run_mode<>rm_dpmi then
- exit;
- linearaddr:=dword(@data)+get_segment_base_address(get_ds);
- unlock_data:=unlock_linear_region(linearaddr,size);
- end;
- function unlock_code(functionaddr : pointer;size : longint) : boolean;
- var
- linearaddr : dword;
- begin
- if get_run_mode<>rm_dpmi then
- exit;
- linearaddr:=dword(functionaddr)+get_segment_base_address(get_cs);
- unlock_code:=unlock_linear_region(linearaddr,size);
- end;
- function set_segment_base_address(d : word;s : dword) : boolean;
- begin
- asm
- pushl %ebx
- movw d,%bx
- leal s,%eax
- movw (%eax),%dx
- movw 2(%eax),%cx
- movl $7,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function set_descriptor_access_right(d : word;w : word) : boolean;
- begin
- asm
- pushl %ebx
- movw d,%bx
- movw w,%cx
- movl $9,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function set_segment_limit(d : word;s : dword) : boolean;
- begin
- asm
- pushl %ebx
- movw d,%bx
- leal s,%eax
- movw (%eax),%dx
- movw 2(%eax),%cx
- movl $8,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ebx
- end;
- end;
- function get_descriptor_access_right(d : word) : longint;
- begin
- asm
- movzwl d,%eax
- lar %eax,%eax
- jz .L_ok
- xorl %eax,%eax
- .L_ok:
- movl %eax,__RESULT
- end;
- end;
- function get_segment_limit(d : word) : dword;
- begin
- asm
- movzwl d,%eax
- lsl %eax,%eax
- jz .L_ok2
- xorl %eax,%eax
- .L_ok2:
- movl %eax,__RESULT
- end;
- end;
- function create_code_segment_alias_descriptor(seg : word) : word;
- begin
- asm
- pushl %ebx
- movw seg,%bx
- movl $0xa,%eax
- int $0x31
- pushf
- call test_int31
- movw %ax,__RESULT
- popl %ebx
- end;
- end;
- function get_meminfo(var meminfo : tmeminfo) : boolean;
- begin
- asm
- pushl %edi
- movl meminfo,%edi
- movl $0x500,%eax
- int $0x31
- pushf
- movb %al,__RESULT
- call test_int31
- popl %edi
- end;
- end;
- function get_linear_addr(phys_addr : dword;size : longint) : dword;
- begin
- asm
- pushl %ebx
- pushl %edi
- pushl %esi
- movl phys_addr,%ebx
- movl %ebx,%ecx
- shrl $16,%ebx
- movl size,%esi
- movl %esi,%edi
- shrl $16,%esi
- movl $0x800,%eax
- int $0x31
- pushf
- call test_int31
- shll $16,%ebx
- movw %cx,%bx
- movl %ebx,__RESULT
- popl %esi
- popl %edi
- popl %ebx
- end;
- end;
- function free_linear_addr_mapping(linear_addr: dword): boolean;
- begin
- asm
- pushl %ebx
- pushl %ecx
- movl linear_addr,%ebx
- movl %ebx,%ecx
- shrl $16,%ebx
- movl $0x801,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %ecx
- popl %ebx
- end;
- end;
- {$ifdef VER3_0}
- procedure disable;assembler;
- asm
- cli
- end;
- procedure enable;assembler;
- asm
- sti
- end;
- {$else VER3_0}
- procedure disable;inline;
- begin
- fpc_x86_cli;
- end;
- procedure enable;inline;
- begin
- fpc_x86_sti;
- end;
- {$endif VER3_0}
- var
- _run_mode : word;external name '_run_mode';
- function get_run_mode : word;
- begin
- get_run_mode:=_run_mode;
- end;
- function map_device_in_memory_block(handle,offset,pagecount,device:dword):boolean;
- begin
- asm
- pushl %ebx
- pushl %edi
- pushl %esi
- movl device,%edx
- movl handle,%esi
- movl offset,%ebx
- movl pagecount,%ecx
- movl $0x0508,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popl %esi
- popl %edi
- popl %ebx
- end;
- end;
- function get_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
- begin
- asm
- pushl %ebx
- pushl %ecx
- pushl %edx
- pushl %esi
- pushw %es
- pushw %ds
- popw %es
- movl buf,%edx
- movl handle,%esi
- movl offset,%ebx
- movl pagecount,%ecx
- movl $0x0506,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popw %es
- popl %esi
- popl %edx
- popl %ecx
- popl %ebx
- end;
- end;
- function set_page_attributes(handle, offset, pagecount: dword; buf: pointer): boolean;
- begin
- asm
- pushl %ebx
- pushl %ecx
- pushl %edx
- pushl %esi
- pushw %es
- pushw %ds
- popw %es
- movl buf,%edx
- movl handle,%esi
- movl offset,%ebx
- movl pagecount,%ecx
- movl $0x0507,%eax
- int $0x31
- pushf
- call test_int31
- movb %al,__RESULT
- popw %es
- popl %esi
- popl %edx
- popl %ecx
- popl %ebx
- end;
- end;
- function get_dpmi_version(var version: tdpmiversioninfo): boolean;
- var
- _version, _flags, _cpu, _pic: word;
- begin
- asm
- movl $0x0400,%eax
- int $0x31
- pushf
- movw %ax,_version
- movw %bx,_flags
- movw %cx,_cpu
- movw %dx,_pic
- call test_int31
- movb %al,__RESULT
- end ['EAX','EBX','ECX','EDX'];
- if get_dpmi_version then
- begin
- FillChar(version, SizeOf(version), 0);
- version.major := _version shr 8;
- version.minor := _version and $ff;
- version.flags := _flags;
- version.cpu := _cpu and $ff;
- version.master_pic := _pic shr 8;
- version.slave_pic := _pic and $ff;
- end;
- end;
- {*****************************************************************************
- Transfer Buffer
- *****************************************************************************}
- function transfer_buffer : longint;
- begin
- transfer_buffer := go32_info_block.linear_address_of_transfer_buffer;
- end;
- function tb_segment : longint;
- begin
- tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
- end;
- function tb_offset : longint;
- begin
- tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
- end;
- function tb_size : longint;
- begin
- tb_size := go32_info_block.size_of_transfer_buffer;
- end;
- procedure copytodos(var addr; len : longint);
- begin
- if len>tb_size then
- runerror(217);
- seg_move(get_ds,longint(@addr),dosmemselector,transfer_buffer,len);
- end;
- procedure copyfromdos(var addr; len : longint);
- begin
- if len>tb_size then
- runerror(217);
- seg_move(dosmemselector,transfer_buffer,get_ds,longint(@addr),len);
- end;
- var
- _core_selector : word;external name '_core_selector';
- begin
- int31error:=0;
- dosmemselector:=_core_selector;
- end.
|