mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 07:59:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			335 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			335 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
{
 | 
						|
    This file is part of the Free Pascal run time library.
 | 
						|
    Copyright (c) 2001 by Free Pascal development team
 | 
						|
 | 
						|
    This file implements all the base types and limits required
 | 
						|
    for a minimal POSIX compliant subset required to port the compiler
 | 
						|
    to a new OS.
 | 
						|
 | 
						|
    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.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
 | 
						|
const
 | 
						|
  carryflag = 1;
 | 
						|
 | 
						|
type
 | 
						|
  tseginfo=packed record
 | 
						|
    offset  : pointer;
 | 
						|
    segment : word;
 | 
						|
  end;
 | 
						|
 | 
						|
var
 | 
						|
  old_int00 : tseginfo;cvar;
 | 
						|
  old_int75 : tseginfo;cvar;
 | 
						|
 | 
						|
{$asmmode ATT}
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                              Go32 Helpers
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
function far_strlen(selector : word;linear_address : longint) : longint;assembler;
 | 
						|
asm
 | 
						|
        movl linear_address,%edx
 | 
						|
        movl %edx,%ecx
 | 
						|
        movw selector,%gs
 | 
						|
.Larg19:
 | 
						|
        movb %gs:(%edx),%al
 | 
						|
        testb %al,%al
 | 
						|
        je .Larg20
 | 
						|
        incl %edx
 | 
						|
        jmp .Larg19
 | 
						|
.Larg20:
 | 
						|
        movl %edx,%eax
 | 
						|
        subl %ecx,%eax
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function tb : longint;
 | 
						|
begin
 | 
						|
  tb:=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;
 | 
						|
 | 
						|
 | 
						|
function dos_selector : word;
 | 
						|
begin
 | 
						|
  dos_selector:=go32_info_block.selector_for_linear_memory;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function get_ds : word;assembler;
 | 
						|
asm
 | 
						|
        movw    %ds,%ax
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function get_cs : word;assembler;
 | 
						|
asm
 | 
						|
        movw    %cs,%ax
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure sysseg_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
 | 
						|
   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;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function strcopy(dest,source : pchar) : pchar;assembler;
 | 
						|
var
 | 
						|
  saveeax,saveesi,saveedi : longint;
 | 
						|
asm
 | 
						|
        movl    %edi,saveedi
 | 
						|
        movl    %esi,saveesi
 | 
						|
{$ifdef REGCALL}
 | 
						|
        movl    %eax,saveeax
 | 
						|
        movl    %edx,%edi
 | 
						|
{$else}
 | 
						|
        movl    source,%edi
 | 
						|
{$endif}
 | 
						|
        testl   %edi,%edi
 | 
						|
        jz      .LStrCopyDone
 | 
						|
        leal    3(%edi),%ecx
 | 
						|
        andl    $-4,%ecx
 | 
						|
        movl    %edi,%esi
 | 
						|
        subl    %edi,%ecx
 | 
						|
{$ifdef REGCALL}
 | 
						|
        movl    %eax,%edi
 | 
						|
{$else}
 | 
						|
        movl    dest,%edi
 | 
						|
{$endif}
 | 
						|
        jz      .LStrCopyAligned
 | 
						|
.LStrCopyAlignLoop:
 | 
						|
        movb    (%esi),%al
 | 
						|
        incl    %edi
 | 
						|
        incl    %esi
 | 
						|
        testb   %al,%al
 | 
						|
        movb    %al,-1(%edi)
 | 
						|
        jz      .LStrCopyDone
 | 
						|
        decl    %ecx
 | 
						|
        jnz     .LStrCopyAlignLoop
 | 
						|
        .balign  16
 | 
						|
.LStrCopyAligned:
 | 
						|
        movl    (%esi),%eax
 | 
						|
        movl    %eax,%edx
 | 
						|
        leal    0x0fefefeff(%eax),%ecx
 | 
						|
        notl    %edx
 | 
						|
        addl    $4,%esi
 | 
						|
        andl    %edx,%ecx
 | 
						|
        andl    $0x080808080,%ecx
 | 
						|
        jnz     .LStrCopyEndFound
 | 
						|
        movl    %eax,(%edi)
 | 
						|
        addl    $4,%edi
 | 
						|
        jmp     .LStrCopyAligned
 | 
						|
.LStrCopyEndFound:
 | 
						|
        testl   $0x0ff,%eax
 | 
						|
        jz      .LStrCopyByte
 | 
						|
        testl   $0x0ff00,%eax
 | 
						|
        jz      .LStrCopyWord
 | 
						|
        testl   $0x0ff0000,%eax
 | 
						|
        jz      .LStrCopy3Bytes
 | 
						|
        movl    %eax,(%edi)
 | 
						|
        jmp     .LStrCopyDone
 | 
						|
.LStrCopy3Bytes:
 | 
						|
        xorb     %dl,%dl
 | 
						|
        movw     %ax,(%edi)
 | 
						|
        movb     %dl,2(%edi)
 | 
						|
        jmp     .LStrCopyDone
 | 
						|
.LStrCopyWord:
 | 
						|
        movw    %ax,(%edi)
 | 
						|
        jmp     .LStrCopyDone
 | 
						|
.LStrCopyByte:
 | 
						|
        movb    %al,(%edi)
 | 
						|
.LStrCopyDone:
 | 
						|
{$ifdef REGCALL}
 | 
						|
        movl    saveeax,%eax
 | 
						|
{$else}
 | 
						|
        movl    dest,%eax
 | 
						|
{$endif}
 | 
						|
        movl    saveedi,%edi
 | 
						|
        movl    saveesi,%esi
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure syscopytodos(addr : longint; len : longint);
 | 
						|
begin
 | 
						|
   if len > tb_size then
 | 
						|
     HandleError(217);
 | 
						|
   sysseg_move(get_ds,addr,dos_selector,tb,len);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure syscopyfromdos(addr : longint; len : longint);
 | 
						|
begin
 | 
						|
   if len > tb_size then
 | 
						|
     HandleError(217);
 | 
						|
   sysseg_move(dos_selector,tb,get_ds,addr,len);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure sysrealintr(intnr : word;var regs : trealregs);
 | 
						|
begin
 | 
						|
   regs.realsp:=0;
 | 
						|
   regs.realss:=0;
 | 
						|
   regs.realres:=0; { spec says so, play it safe }
 | 
						|
   asm
 | 
						|
      pushl %ebx
 | 
						|
      pushl %edi
 | 
						|
      pushl %fs   // Go32.RealIntr does it too (NTVDM bug),
 | 
						|
                  // "pushl" to avoid size prefix
 | 
						|
      movw  intnr,%bx
 | 
						|
      xorl  %ecx,%ecx
 | 
						|
      movl  regs,%edi
 | 
						|
      movw  $0x300,%ax
 | 
						|
      int   $0x31
 | 
						|
      popl  %fs
 | 
						|
      popl  %edi
 | 
						|
      popl  %ebx
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure set_pm_interrupt(vector : byte;const intaddr : tseginfo);
 | 
						|
begin
 | 
						|
  asm
 | 
						|
        pushl   %ebx
 | 
						|
        movl intaddr,%eax
 | 
						|
        movl (%eax),%edx
 | 
						|
        movw 4(%eax),%cx
 | 
						|
        movl $0x205,%eax
 | 
						|
        movb vector,%bl
 | 
						|
        int $0x31
 | 
						|
        popl  %ebx
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure get_pm_interrupt(vector : byte;var intaddr : tseginfo);
 | 
						|
begin
 | 
						|
  asm
 | 
						|
        pushl   %ebx
 | 
						|
        movb    vector,%bl
 | 
						|
        movl    $0x204,%eax
 | 
						|
        int     $0x31
 | 
						|
        movl    intaddr,%eax
 | 
						|
        movl    %edx,(%eax)
 | 
						|
        movw    %cx,4(%eax)
 | 
						|
        popl  %ebx
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure getinoutres(def : word);
 | 
						|
var
 | 
						|
  regs : trealregs;
 | 
						|
begin
 | 
						|
  regs.realeax:=$5900;
 | 
						|
  regs.realebx:=$0;
 | 
						|
  sysrealintr($21,regs);
 | 
						|
  InOutRes:=lo(regs.realeax);
 | 
						|
  case InOutRes of
 | 
						|
   19 : InOutRes:=150;
 | 
						|
   21 : InOutRes:=152;
 | 
						|
   32 : InOutRes:=5;
 | 
						|
  end;
 | 
						|
  if InOutRes=0 then
 | 
						|
    InOutRes:=Def;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
 |