| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 | {    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        pushl %gs        movw selector,%gs.Larg19:        movb %gs:(%edx),%al        testb %al,%al        je .Larg20        incl %edx        jmp .Larg19.Larg20:        popl %gs        movl %edx,%eax        subl %ecx,%eaxend;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,%axend;function get_cs : word;assembler;asm        movw    %cs,%axend;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,%esiend;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;
 |