Ver Fonte

* objects compiles for linux
+ assign(pchar), assign(char), rename(pchar), rename(char)
* fixed read_text_as_array
+ read_text_as_pchar which was not yet in the rtl

peter há 27 anos atrás
pai
commit
eb39182b3b
13 ficheiros alterados com 1050 adições e 1119 exclusões
  1. 169 264
      rtl/dos/crt.pp
  2. 431 549
      rtl/dos/dos.pp
  3. 18 6
      rtl/dos/go32v2/emu387.pp
  4. 192 214
      rtl/dos/go32v2/system.pp
  5. 48 8
      rtl/inc/file.inc
  6. 22 56
      rtl/inc/getopts.pp
  7. 23 6
      rtl/inc/objects.pp
  8. 10 1
      rtl/inc/platform.inc
  9. 21 3
      rtl/inc/systemh.inc
  10. 77 10
      rtl/inc/text.inc
  11. 28 1
      rtl/inc/typefile.inc
  12. 3 1
      rtl/linux/makefile
  13. 8 0
      rtl/linux/objinc.inc

+ 169 - 264
rtl/dos/crt.pp

@@ -12,128 +12,108 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
-{
-  history:
-  29th may 1994: version 1.0
-             unit is completed
-  14th june 1994: version 1.01
-             the address from which startaddr was read wasn't right; fixed
-  18th august 1994: version 1.1
-             the upper left corner of winmin is now 0,0
-  19th september 1994: version 1.11
-             keypressed handles extended keycodes false; fixed
-  27th february 1995: version 1.12
-             * crtinoutfunc didn't the line wrap in the right way;
-               fixed
-  20th january 1996: version 1.13
-             - unused variables removed
-  21th august 1996: version 1.14
-             * adapted to newer FPKPascal versions
-             * make the comments english
-   6th november 1996: version 1.49
-             * some stuff for DPMI adapted
-  15th november 1996: version 1.5
-             * bug in screenrows fixed
-  13th november 1997: removed textrec definition, is now included from 
-               textrec.inc
-}
-
 unit crt;
+interface
 
 {$I os.inc}
 
-  interface
-  
-    uses
-       go32;
-
-    const
-       { screen modes }
-       bw40 = 0;
-       co40 = 1;
-       bw80 = 2;
-       co80 = 3;
-       mono = 7;
-       font8x8 = 256;
-
-       { screen color, fore- and background }
-       black = 0;
-       blue = 1;
-       green = 2;
-       cyan = 3;
-       red = 4;
-       magenta = 5;
-       brown = 6;
-       lightgray = 7;
-
-       { only foreground }
-       darkgray = 8;
-       lightblue = 9;
-       lightgreen = 10;
-       lightcyan = 11;
-       lightred = 12;
-       lightmagenta = 13;
-       yellow = 14;
-       white = 15;
-
-       { blink flag }
-       blink = $80;
 
-    const
-    {$ifndef GO32V2}
-       directvideo:boolean=true;
-    {$else GO32V2}
-       { direct video generates a GPF in DPMI of setcursor }
-       directvideo:boolean=false;
-    {$endif GO32V2}
+const
+{ CRT modes }
+  BW40          = 0;            { 40x25 B/W on Color Adapter }
+  CO40          = 1;            { 40x25 Color on Color Adapter }
+  BW80          = 2;            { 80x25 B/W on Color Adapter }
+  CO80          = 3;            { 80x25 Color on Color Adapter }
+  Mono          = 7;            { 80x25 on Monochrome Adapter }
+  Font8x8       = 256;          { Add-in for ROM font }
+
+{ Mode constants for 3.0 compatibility }
+  C40           = CO40;
+  C80           = CO80;
+
+{ Foreground and background color constants }
+  Black         = 0;
+  Blue          = 1;
+  Green         = 2;
+  Cyan          = 3;
+  Red           = 4;
+  Magenta       = 5;
+  Brown         = 6;
+  LightGray     = 7;
+
+{ Foreground color constants }
+  DarkGray      = 8;
+  LightBlue     = 9;
+  LightGreen    = 10;
+  LightCyan     = 11;
+  LightRed      = 12;
+  LightMagenta  = 13;
+  Yellow        = 14;
+  White         = 15;
+
+{ Add-in for blinking }
+  Blink         = 128;
 
-    var
-       { for compatibility }
-       checkbreak,checkeof,checksnow : boolean;
+var
 
-       lastmode : word; { screen mode}
-       textattr : byte; { current text attribute }
-       windmin  : word; { upper right corner of the CRT window }
-       windmax  : word; { lower left corner of the CRT window }
+{ Interface variables }
+  CheckBreak: Boolean;    { Enable Ctrl-Break }
+  CheckEOF: Boolean;      { Enable Ctrl-Z }
+  DirectVideo: Boolean;   { Enable direct video addressing }
+  CheckSnow: Boolean;     { Enable snow filtering }
+  LastMode: Word;         { Current text mode }
+  TextAttr: Byte;         { Current text attribute }
+  WindMin: Word;          { Window upper left coordinates }
+  WindMax: Word;          { Window lower right coordinates }
+
+{ Interface procedures }
+procedure AssignCrt(var F: Text);
+function KeyPressed: Boolean;
+function ReadKey: Char;
+procedure TextMode(Mode: Integer);
+procedure Window(X1,Y1,X2,Y2: Byte);
+procedure GotoXY(X,Y: Byte);
+function WhereX: Byte;
+function WhereY: Byte;
+procedure ClrScr;
+procedure ClrEol;
+procedure InsLine;
+procedure DelLine;
+procedure TextColor(Color: Byte);
+procedure TextBackground(Color: Byte);
+procedure LowVideo;
+procedure HighVideo;
+procedure NormVideo;
+procedure Delay(MS: Word);
+procedure Sound(Hz: Word);
+procedure NoSound;
+
+{Extra Functions}
+procedure cursoron;
+procedure cursoroff;
+procedure cursorbig;
+
+
+implementation
+
+uses
+  go32;
 
-    function keypressed : boolean;
-    function readkey : char;
-    procedure gotoxy(x,y : byte);
-    procedure window(left,top,right,bottom : byte);
-    procedure clrscr;
-    procedure textcolor(color : byte);
-    procedure textbackground(color : byte);
-    procedure assigncrt(var f : text);
-    function wherex : byte;
-    function wherey : byte;
-    procedure delline;
-    procedure delline(line : byte);
-    procedure clreol;
-    procedure insline;
-    procedure cursoron;
-    procedure cursoroff;
-    procedure cursorbig;
-    procedure lowvideo;
-    procedure highvideo;
-    procedure nosound;
-    procedure sound(hz : word);
-    procedure delay(ms : longint);
-    procedure textmode(mode : integer);
-    procedure normvideo;
-    
-  implementation
-  
-    var
-       maxcols,maxrows : longint;
-
-    { definition of textrec is in textrec.inc}
+var
+  startattrib     : byte;
+  col,row,
+  maxcols,maxrows : longint;
 
-    {$i textrec.inc}
+{
+  definition of textrec is in textrec.inc
+}
+{$i textrec.inc}
 
-    { low level routines }
+{****************************************************************************
+                           Low level Routines
+****************************************************************************}
 
     function getscreenmode : byte;
-
       begin
          dosmemget($40,$49,getscreenmode,1);
       end;
@@ -230,6 +210,8 @@ unit crt;
          row:=0;
          dosmemget($40,$50,col,1);
          dosmemget($40,$51,row,1);
+         inc(col);
+         inc(row);
       end;
 
     { exported routines }
@@ -397,7 +379,7 @@ unit crt;
 
      begin
         screengetcursor(row,col);
-        wherex:=col-lo(windmin)+1;
+        wherex:=col-lo(windmin);
      end;
 
    function wherey : byte;
@@ -407,29 +389,23 @@ unit crt;
 
      begin
         screengetcursor(row,col);
-        wherey:=row-hi(windmin)+1;
+        wherey:=row-hi(windmin);
      end;
 
-   procedure window(left,top,right,bottom : byte);
-
+   procedure Window(X1,Y1,X2,Y2: Byte);
      begin
-        if (left<1) or
-           (right>screencols) or
-           (bottom>screenrows) or
-           (left>right) or
-           (top>bottom) then
-           exit;
-        windmin:=(left-1) or ((top-1) shl 8);
-        windmax:=(right-1) or ((bottom-1) shl 8);
+        if (x1<1) or (x2>screencols) or (y2>screenrows) or
+           (x1>x2) or (y1>y2) then
+          exit;
+        windmin:=(x1-1) or ((x1-1) shl 8);
+        windmax:=(x2-1) or ((y2-1) shl 8);
         gotoxy(1,1);
      end;
 
    procedure clrscr;
-
      var
         fil : word;
         row : longint;
-
      begin
         fil:=32 or (textattr shl 8);
         for row:=hi(windmin) to hi(windmax) do
@@ -437,45 +413,41 @@ unit crt;
         gotoxy(1,1);
      end;
 
-   procedure textcolor(color : Byte);
 
+   procedure textcolor(color : Byte);
      begin
         textattr:=(textattr and $70) or color;
      end;
 
-   procedure lowvideo;
 
+   procedure lowvideo;
      begin
         textattr:=textattr and $f7;
      end;
 
-   procedure highvideo;
 
+   procedure highvideo;
      begin
         textattr:=textattr or $08;
      end;
 
-   procedure textbackground(color : Byte);
 
+   procedure textbackground(color : Byte);
      begin
         textattr:=(textattr and $8f) or ((color and $7) shl 4);
      end;
 
-   var
-      startattrib : byte;
 
    procedure normvideo;
-
      begin
         textattr:=startattrib;
      end;
 
-   procedure delline(line : byte);
 
+   procedure removeline(line : byte);
      var
         row,left,right,bot : longint;
         fil : word;
-
      begin
         row:=line+hi(windmin);
         left:=lo(windmin)+1;
@@ -490,10 +462,10 @@ unit crt;
         dosmemfillword($b800,get_addr(bot,left),right-left+1,fil);
      end;
 
-   procedure delline;
 
+   procedure delline;
      begin
-        delline(wherey);
+        removeline(wherey);
      end;
 
    procedure insline;
@@ -518,11 +490,9 @@ unit crt;
      end;
 
    procedure clreol;
-
      var
         row,col : longint;
         fil : word;
-
      begin
         screengetcursor(row,col);
         inc(row);
@@ -532,61 +502,52 @@ unit crt;
      end;
 
 
-   Function CrtWrite(var f : textrec):integer;
+   Procedure WriteChar(c:char);
+     var
+       sa   : longint;
+       regs : trealregs;
+     begin
+       case c of
+        #10 : inc(row);
+        #13 : col:=lo(windmin)+1;
+         #8 : begin
+                if col>lo(windmin)+1 then
+                 dec(col);
+              end;
+         #7 : begin { beep }
+                regs.dl:=7;
+                regs.ah:=2;
+                realintr($21,regs);
+              end;
+       else
+        begin
+          sa:=(textattr shl 8) or byte(c);
+          dosmemput($b800,get_addr(row,col),sa,sizeof(sa));
+          inc(col);
+        end;
+       end;
+       if col>lo(windmax)+1 then
+        begin
+          col:=lo(windmin)+1;
+          inc(row);
+        end;
+       while row>hi(windmax)+1 do
+        begin
+          removeline(1);
+          dec(row);
+        end;
+     end;
 
-      var
-         i,col,row : longint;
-         c : char;
-         va,sa : word;
 
+   Function CrtWrite(var f : textrec):integer;
+      var
+         i : longint;
       begin
          screengetcursor(row,col);
          inc(row);
          inc(col);
-         va:=get_addr(row,col);
          for i:=0 to f.bufpos-1 do
-           begin
-              c:=f.buffer[i];
-              case ord(c) of
-                 10 : begin
-                         inc(row);
-                         va:=va+maxcols*2;
-                      end;
-                 13 : begin
-                         col:=lo(windmin)+1;
-                         va:=get_addr(row,col);
-                     end;
-                 8 : if col>lo(windmin)+1 then
-                       begin
-                          dec(col);
-                          va:=va-2;
-                       end;
-                 7 : begin
-                         { beep }
-                      end;
-              else
-                 begin
-                    sa:=textattr shl 8 or ord(c);
-                    dosmemput($b800,va,sa,sizeof(sa));
-                    inc(col);
-                    va:=va+2;
-                 end;
-              end;
-              if col>lo(windmax)+1 then
-                begin
-                   col:=lo(windmin)+1;
-                   inc(row);
-                   { it's easier to calculate the new address }
-                   { it don't spend much time                 }
-                   va:=get_addr(row,col);
-                end;
-              while row>hi(windmax)+1 do
-                begin
-                   delline(1);
-                   dec(row);
-                   va:=va-maxcols*2;
-                end;
-           end;
+          WriteChar(f.buffer[i]);
          f.bufpos:=0;
          screensetcursor(row-1,col-1);
          CrtWrite:=0;
@@ -608,9 +569,7 @@ unit crt;
 
    Function CrtRead(Var F: TextRec): Integer;
      Begin
-     {$IFDEF GO32V2}
        f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
-     {$ENDIF}
        f.bufpos:=0;
        CrtRead:=0;
      End;
@@ -623,18 +582,13 @@ unit crt;
        End;
      End;
 
-   procedure assigncrt(var f : text);
+   procedure AssignCrt(var F: Text);
      begin
-        TextRec(F).Mode:=fmClosed;
-        TextRec(F).BufSize:=SizeOf(TextBuf);
-        TextRec(F).BufPtr:=@TextRec(F).Buffer;
-        TextRec(F).BufPos:=0;
-        TextRec(F).OpenFunc:=@CrtOpen;
-        TextRec(F).InOutFunc:=@CrtInOut;
-        TextRec(F).FlushFunc:=@CrtInOut;
-        TextRec(F).CloseFunc:=@CrtClose;
-        TextRec(F).Name[0]:='.';
-        TextRec(F).Name[1]:=#0;
+       Assign(F,'.');
+       TextRec(F).OpenFunc:=@CrtOpen;
+       TextRec(F).InOutFunc:=@CrtInOut;
+       TextRec(F).FlushFunc:=@CrtInOut;
+       TextRec(F).CloseFunc:=@CrtClose;
      end;
 
    procedure sound(hz : word);
@@ -648,7 +602,7 @@ unit crt;
         asm
            movzwl hz,%ecx
            movl $1193046,%eax
-	   cdq
+           cdq
            divl %ecx
            movl %eax,%ecx
            movb $0xb6,%al
@@ -676,11 +630,9 @@ unit crt;
    var
       calibration : longint;
 
-   procedure delay(ms : longint);
-
+   procedure Delay(MS: Word);
       var
          i,j : longint;
-
      begin
         for i:=1 to ms do
           for j:=1 to calibration do
@@ -695,8 +647,10 @@ unit crt;
     end;
 
   procedure initdelay;
-  
-       { From the mailling list, 
+
+
+       { From the mailling list,
+
          by Jonathan Anderson ([email protected]) }
 
     const
@@ -739,7 +693,8 @@ unit crt;
 
        if calibration<(threshold+1)*2 then
           calibration:=(threshold+1)*2;
-          
+
+
        { If calibration is not at least this value, an }
        { infinite loop will result.                    }
 
@@ -788,10 +743,8 @@ unit crt;
 
 
   procedure textmode(mode : integer);
-
     var
        set_font8x8 : boolean;
-
     begin
        lastmode:=mode;
        set_font8x8:=(mode and font8x8)<>0;
@@ -803,8 +756,6 @@ unit crt;
        maxrows:=screenrows;
     end;
 
-var
-   col,row : longint;
 
 begin
    is_last:=false;
@@ -824,11 +775,9 @@ begin
 
    { redirect the standard output }
    assigncrt(Output);
-   TextRec(Output).mode:=fmOutput;
-{$IFDEF GO32V2}
    assigncrt(Input);
+   TextRec(Output).mode:=fmOutput;
    TextRec(Input).mode:=fmInput;
-{$ENDIF GO32V2}
 
    { calculates delay calibration }
    initdelay;
@@ -836,56 +785,12 @@ end.
 
 {
   $Log$
-  Revision 1.1  1998-03-25 11:18:41  root
-  Initial revision
-
-  Revision 1.8  1998/01/26 11:56:39  michael
-  + Added log at the end
-
-
-  
-  Working file: rtl/dos/crt.pp
-  description:
-  ----------------------------
-  revision 1.7
-  date: 1998/01/07 09:24:18;  author: michael;  state: Exp;  lines: +7 -2
-  * Bug fixed in initdelay, avoiding possible infiniteloop.
-  ----------------------------
-  revision 1.6
-  date: 1998/01/06 00:29:28;  author: michael;  state: Exp;  lines: +2 -2
-  Implemented a system independent sequence of reset/rewrite/append fileopenfunc etc system \n (from Peter Vreman)
-  ----------------------------
-  revision 1.5
-  date: 1998/01/05 16:52:15;  author: michael;  state: Exp;  lines: +7 -3
-  + Minor change making use of new GO32V2 feature (From Peter Vreman)
-  ----------------------------
-  revision 1.4
-  date: 1998/01/05 13:47:01;  author: michael;  state: Exp;  lines: +199 -127
-  * Bug fixes by Peter Vreman ([email protected]), discovered
-    when writing CRT examples.
-    Bug fix from mailing list also applied.
-  ----------------------------
-  revision 1.3
-  date: 1997/12/12 13:14:36;  author: pierre;  state: Exp;  lines: +33 -12
-     + added handling of swap_vectors if under exceptions
-       i.e. swapvector is not dummy under go32v2
-     * bug in output, exceptions where not allways reset correctly
-       now the code in dpmiexcp is called from v2prt0.as exit routine
-     * in crt.pp corrected init_delay calibration loop
-       and added it for go32v2 also (was disabled before due to crashes !!)
-       the previous code did a wrong assumption on the time need to call
-       get_ticks compared to an internal loop without call
-  ----------------------------
-  revision 1.2
-  date: 1997/12/01 12:15:44;  author: michael;  state: Exp;  lines: +11 -5
-  + added copyright reference in header.
-  ----------------------------
-  revision 1.1
-  date: 1997/11/27 08:33:49;  author: michael;  state: Exp;
-  Initial revision
-  ----------------------------
-  revision 1.1.1.1
-  date: 1997/11/27 08:33:49;  author: michael;  state: Exp;  lines: +0 -0
-  FPC RTL CVS start
-  =============================================================================
+  Revision 1.2  1998-05-21 19:30:46  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
 }
+
+

+ 431 - 549
rtl/dos/dos.pp

@@ -11,292 +11,187 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
  **********************************************************************}
-
-{ to be able to cross compile from v1 to v2 }
+unit dos;
 
 {$I os.inc}
 
+interface
+Uses Go32;
+
+Const
+  {Bitmasks for CPU Flags}
+  fcarry     = $0001;
+  fparity    = $0004;
+  fauxiliary = $0010;
+  fzero      = $0040;
+  fsign      = $0080;
+  foverflow  = $0800;
+
+  {Bitmasks for file attribute}
+  readonly  = $01;
+  hidden    = $02;
+  sysfile   = $04;
+  volumeid  = $08;
+  directory = $10;
+  archive   = $20;
+  anyfile   = $3F;
+
+  {File Status}
+  fmclosed = $D7B0;
+  fminput  = $D7B1;
+  fmoutput = $D7B2;
+  fminout  = $D7B3;
+
+
+Type
+{$IFDEF GO32V2}
+{ Needed for Win95 LFN Support }
+  ComStr  = String[255];
+  PathStr = String[255];
+  DirStr  = String[255];
+  NameStr = String[255];
+  ExtStr  = String[255];
+{$ELSE}
+  comstr  = string[127];        { command line string }
+  pathstr = string[79];         { string for a file path }
+  dirstr  = string[67];         { string for a directory }
+  namestr = string[8];          { string for a file name }
+  extstr  = string[4];          { string for an extension }
+{$ENDIF}
+
 {
-  History:
-  2.7.1994: Version 0.2
-            Datenstrukturen sind deklariert sowie
-            50 % der Unterprogramme sind implementiert
-  12.8.1994: exec implemented
-  14.8.1994: findfirst and findnext implemented
-  24.8.1994: Version 0.3
-  28.2.1995: Version 0.31
-             some parameter lists with const optimized
-   3.7.1996: bug in fsplit removed (dir and ext were not intializised)
-   7.7.1996: packtime and unpacktime implemented
-  20.9.1996: Version 0.5
-             setftime and getftime implemented
-             some optimizations done (integer -> longint)
-             procedure fsearch from the LINUX version ported
-             msdos call implemented
-  26th november 1996:
-             better fexpand
-  29th january 1997:
-             bug in getftime and setftime removed
-             setfattr and getfattr added
-   2th february 1997: Version 0.9
-             bug of searchrec corrected
-  30th may 1997:
-             bug in fsplit fixed (thanks to Pierre Muller):
-               If you have a relative path as argument
-               fsplit gives a wrong result because it
-               first tries to find the extension by searching the first
-               occurence of '.'.
-
-               The file extension should be tested last !!
-  15th june 1997:
-             versions for go32v1 and go32v2 merged
-  september 1997:
-             removed some bugs for go32v2
-             - searchrec structure is different (direct dos call !!)
-  27th november 1997:
-             bug in findfirst fixed esp was instead of ebp used
+  filerec.inc contains the definition of the filerec.
+  textrec.inc contains the definition of the textrec.
+  It is in a separate file to make it available in other units without
+  having to use the DOS unit for it.
 }
+{$i filerec.inc}
+{$i textrec.inc}
 
-{$ifndef GO32V2}
-{$ifdef DOS}
-{$define GO32V1}
-{$endif DOS}
-{$endif not GO32V2}
-
-unit dos;
-
-  interface
-
-    uses
-       strings
-{$ifdef GO32V2}
-       ,go32
-{$endif GO32V2}
-       ;
-
-    const
-       { bit masks for CPU flags}
-       fcarry = $0001;
-       fparity = $0004;
-       fauxiliary = $0010;
-       fzero = $0040;
-       fsign = $0080;
-       foverflow  = $0800;
-
-       { bit masks for file attributes }
-       readonly = $01;
-       hidden = $02;
-       sysfile = $04;
-       volumeid = $08;
-       directory = $10;
-       archive = $20;
-       anyfile = $3F;
-       fmclosed = $D7B0;
-       fminput = $D7B1;
-       fmoutput = $D7B2;
-       fminout = $D7B3;
-
-    type
-       { some string types }
-       comstr = string[127];        { command line string }
-       pathstr = string[79];        { string for a file path }
-       dirstr = string[67];         { string for a directory }
-       namestr = string[8];         { string for a file name }
-       extstr = string[4];          { string for an extension }
-
-       { search record which is used by findfirst and findnext }
-{$ifndef GO32V2}
 {$PACKRECORDS 1}
-       searchrec = record
-          fill : array[1..21] of byte;
-          attr : byte;
-          time : longint;
-          reserved : word; { requires the DOS extender (DJ GNU-C) }
-          size : longint;
-          name : string[15]; { the same size as declared by (DJ GNU C) }
-       end;
-{$else GO32V2}
-{$PACKRECORDS 1}
-       searchrec = record
-          fill : array[1..21] of byte;
-          attr : byte;
-          time : longint;
-          { reserved : word; not in DJGPP V2 }
-          size : longint;
-          name : string[12]; { the same size as declared by (DJ GNU C) }
-       end;
-{$endif GO32V2}
-{$PACKRECORDS 2}
-
-       { file record for untyped files comes from filerec.inc}
-       {$i filerec.inc}
 
-       { file record for text files  comes from textrec.inc}
-       {$i textrec.inc}
-
-{$ifdef GO32V1}
-       { data structure for the registers needed by msdos and intr }
-       { Go32 V2 follows trealregs of go32 }
-
-       registers = record
-         case i : integer of
-            0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
-            1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
-            2 : (eax,  ebx,  ecx,  edx,  ebp,  esi,  edi : longint);
-       end;
+  DateTime = record
+    Year,
+    Month,
+    Day,
+    Hour,
+    Min,
+    Sec   : word;
+  End;
+
+{$IFDEF GO32V2}
+  searchrec = record
+     fill : array[1..21] of byte;
+     attr : byte;
+     time : longint;
+     { reserved : word; not in DJGPP V2 }
+     size : longint;
+     name : string[12]; { the same size as declared by (DJ GNU C) }
+  end;
+
+  Registers = Go32.Registers;
+
+{$ELSE}
+  searchrec = record
+     fill     : array[1..21] of byte;
+     attr     : byte;
+     time     : longint;
+     reserved : word; { requires the DOS extender (DJ GNU-C) }
+     size     : longint;
+     name     : string[15]; { the same size as declared by (DJ GNU C) }
+  end;
+
+  registers = record
+    case i : integer of
+     0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
+     1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
+     2 : (eax,  ebx,  ecx,  edx,  ebp,  esi,  edi : longint);
+    end;
 {$endif GO32V1}
 
-{$ifdef GO32V2}
-       { data structure for the registers needed by msdos and intr }
-       { Go32 V2 follows trealregs of go32 }
-
-       registers = go32.registers;
-
-{$endif GO32V2}
-
-{$PACKRECORDS 1}
-       { record for date and time }
-       datetime = record
-          year,month,day,hour,min,sec : word;
-       end;
-
-    var
-       { error variable }
-       doserror : integer;
-
-    procedure getdate(var year,month,day,dayofweek : word);
-    procedure gettime(var hour,minute,second,sec100 : word);
-    function dosversion : word;
-    procedure setdate(year,month,day : word);
-    procedure settime(hour,minute,second,sec100 : word);
-    procedure getcbreak(var breakvalue : boolean);
-    procedure setcbreak(breakvalue : boolean);
-    procedure getverify(var verify : boolean);
-    procedure setverify(verify : boolean);
-    function diskfree(drive : byte) : longint;
-    function disksize(drive : byte) : longint;
-    procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
-    procedure findnext(var f : searchRec);
-
-    { is a dummy for go32v1 not for go32v2 }
-    procedure swapvectors;
-
-{   not supported:
-    procedure getintvec(intno : byte;var vector : pointer);
-    procedure setintvec(intno : byte;vector : pointer);
-    procedure keep(exitcode : word);
-}
-    procedure msdos(var regs : registers);
-    procedure intr(intno : byte;var regs : registers);
-
-    procedure getfattr(var f;var attr : word);
-    procedure setfattr(var f;attr : word);
-
-    function fsearch(const path : pathstr;dirlist : string) : pathstr;
-    procedure getftime(var f;var time : longint);
-    procedure setftime(var f;time : longint);
-    procedure packtime (var d: datetime; var time: longint);
-    procedure unpacktime (time: longint; var d: datetime);
-    function fexpand(const path : pathstr) : pathstr;
-    procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;
-      var ext : extstr);
-    procedure exec(const path : pathstr;const comline : comstr);
-    function dosexitcode : word;
-    function envcount : longint;
-    function envstr(index : longint) : string;
-    function getenv(const envvar : string): string;
-
-  implementation
-
-    var
-       dosregs : registers;
-
-    { this was first written for the LINUX version,    }
-    { by Michael Van Canneyt but it works also         }
-    { for the DOS version (I hope so)                  }
-    function fsearch(const path : pathstr;dirlist : string) : pathstr;
-
-      var
-         newdir : pathstr;
-         i,p1 : byte;
-         s : searchrec;
-
-      begin
-         if (pos('?',path)<>0) or (pos('*',path)<>0) then
-           { No wildcards allowed in these things }
-           fsearch:=''
-         else
-           begin
-              { allow slash as backslash }
-              for i:=1 to length(dirlist) do
-                if dirlist[i]='/' then dirlist[i]:='\';
-
-              repeat
-                { get first path }
-                p1:=pos(';',dirlist);
-                if p1>0 then
-                  begin
-                     newdir:=copy(dirlist,1,p1-1);
-                     delete(dirlist,1,p1)
-                  end
-                else
-                  begin
-                     newdir:=dirlist;
-                     dirlist:=''
-                  end;
-                if (newdir[length(newdir)]<>'\') and
-                   (newdir[length(newdir)]<>':') then
-                   newdir:=newdir+'\';
-                findfirst(newdir+path,anyfile,s);
-                if doserror=0 then
-                  begin
-                     { this should be newdir:=newdir+path
-                     because path can contain a path part !! }
-                     {newdir:=newdir+s.name;}
-                     newdir:=newdir+path;
-                     { this was for LINUX:
-                     if pos('.\',newdir)=1 then
-                       delete(newdir, 1, 2)
-                      DOS strips off an initial .\
-                     }
-                  end
-                else newdir:='';
-              until(dirlist='') or (length(newdir)>0);
-              fsearch:=newdir;
-           end;
-      end;
-
-    procedure getftime(var f;var time : longint);
-
-      begin
-         dosregs.bx:=textrec(f).handle;
-         dosregs.ax:=$5700;
-         msdos(dosregs);
-         time:=(dosregs.dx shl 16)+dosregs.cx;
-         doserror:=dosregs.al;
-      end;
-
-   procedure setftime(var f;time : longint);
+{$PACKRECORDS 2}
 
-      begin
-         dosregs.bx:=textrec(f).handle;
-         dosregs.ecx:=time;
-         dosregs.ax:=$5701;
-         msdos(dosregs);
-         doserror:=dosregs.al;
+Var
+  DosError : integer;
+
+{Interrupt}
+Procedure Intr(intno: byte; var regs: registers);
+Procedure MSDos(var regs: registers);
+
+{Info/Date/Time}
+Function  DosVersion: Word;
+Procedure GetDate(var year, month, mday, wday: word);
+Procedure GetTime(var hour, minute, second, sec100: word);
+procedure SetDate(year,month,day: word);
+Procedure SetTime(hour,minute,second,sec100: word);
+Procedure UnpackTime(p: longint; var t: datetime);
+Procedure PackTime(var t: datetime; var p: longint);
+
+{Exec}
+Procedure Exec(const path: pathstr; const comline: comstr);
+Function  DosExitCode: word;
+
+{Disk}
+Function  DiskFree(drive: byte) : longint;
+Function  DiskSize(drive: byte) : longint;
+Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
+Procedure FindNext(var f: searchRec);
+Procedure FindClose(Var f: SearchRec);
+
+{File}
+Procedure GetFAttr(var f; var attr: word);
+Procedure GetFTime(var f; var time: longint);
+Function  FSearch(path: pathstr; dirlist: string): pathstr;
+Function  FExpand(const path: pathstr): pathstr;
+Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
+
+{Environment}
+Function  EnvCount: longint;
+Function  EnvStr(index: integer): string;
+Function  GetEnv(envvar: string): string;
+
+{Misc}
+Procedure SetFAttr(var f; attr: word);
+Procedure SetFTime(var f; time: longint);
+Procedure GetCBreak(var breakvalue: boolean);
+Procedure SetCBreak(breakvalue: boolean);
+Procedure GetVerify(var verify: boolean);
+Procedure SetVerify(verify: boolean);
+
+{Do Nothing Functions}
+Procedure SwapVectors;
+Procedure GetIntVec(intno: byte; var vector: pointer);
+Procedure SetIntVec(intno: byte; vector: pointer);
+Procedure Keep(exitcode: word);
+
+implementation
+
+uses
+
+  strings;
+
+{******************************************************************************
+                           --- Dos Interrupt ---
+******************************************************************************}
+
+var
+  dosregs : registers;
+
+    procedure LoadDosError;
+      begin
+        if (dosregs.flags and carryflag) <> 0 then
+         doserror:=dosregs.ax
+        else
+         doserror:=0;
       end;
 
-    procedure msdos(var regs : registers);
-
-      begin
-         intr($21,regs);
-      end;
 {$ifdef GO32V2}
-    procedure intr(intno : byte;var regs : registers);
 
+    procedure intr(intno : byte;var regs : registers);
       begin
          realintr(intno,regs);
       end;
+
 {$else GO32V2}
     procedure intr(intno : byte;var regs : registers);
 
@@ -353,8 +248,86 @@ unit dos;
          end;
       end;
 {$endif GO32V2}
+
+    procedure msdos(var regs : registers);
+      begin
+         intr($21,regs);
+      end;
+
+{******************************************************************************
+                        --- Info / Date / Time ---
+******************************************************************************}
+
+    function dosversion : word;
+      begin
+         dosregs.ax:=$3000;
+         msdos(dosregs);
+         dosversion:=dosregs.ax;
+      end;
+
+    procedure getdate(var year,month,mday,wday : word);
+      begin
+         dosregs.ax:=$2a00;
+         msdos(dosregs);
+         wday:=dosregs.al;
+         year:=dosregs.cx;
+         month:=dosregs.dh;
+         mday:=dosregs.dl;
+      end;
+
+    procedure setdate(year,month,day : word);
+      begin
+         dosregs.cx:=year;
+         dosregs.dh:=month;
+         dosregs.dl:=day;
+         dosregs.ah:=$2b;
+         msdos(dosregs);
+         LoadDosError;
+      end;
+
+    procedure gettime(var hour,minute,second,sec100 : word);
+      begin
+         dosregs.ah:=$2c;
+         msdos(dosregs);
+         hour:=dosregs.ch;
+         minute:=dosregs.cl;
+         second:=dosregs.dh;
+         sec100:=dosregs.dl;
+      end;
+
+    procedure settime(hour,minute,second,sec100 : word);
+      begin
+         dosregs.ch:=hour;
+         dosregs.cl:=minute;
+         dosregs.dh:=second;
+         dosregs.dl:=sec100;
+         dosregs.ah:=$2d;
+         msdos(dosregs);
+         LoadDosError;
+      end;
+
+   Procedure packtime(var t : datetime;var p : longint);
+       Begin
+         p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
+       End;
+
+   Procedure unpacktime(p : longint;var t : datetime);
+       Begin
+         t.sec:=(p and 31) shl 1;
+         t.min:=(p shr 5) and 63;
+         t.hour:=(p shr 11) and 31;
+         t.day:=(p shr 16) and 31;
+         t.month:=(p shr 21) and 15;
+         t.year:=(p shr 25)+1980;
+       End;
+
+{******************************************************************************
+                               --- Exec ---
+******************************************************************************}
+
     var
        lastdosexitcode : word;
+
 {$ifdef GO32V2}
 
     { this code is just the most basic part of dosexec.c from
@@ -377,8 +350,6 @@ unit dos;
          0Eh    DWORD   (AL=01h) will hold subprogram's initial SS:SP on return
          12h    DWORD   (AL=01h) will hold entry point (CS:IP) on return
         INT 21 4B--
-
-        Copied from Ralf Brown's Interrupt List
       }
 
       type
@@ -401,10 +372,7 @@ unit dos;
         begin
            paste_to_dos:=false;
            if current_dos_buffer_pos+length(src)+1>transfer_buffer+tb_size then
-             begin
-              doserror:=200;{ what value should we use here ? }
-              exit;
-             end;
+            RunError(217);
            move(src[1],c[0],length(src));
            c[length(src)]:=#0;
            seg_move(get_ds,longint(@c),dosmemselector,current_dos_buffer_pos,length(src)+1);
@@ -480,18 +448,15 @@ unit dos;
          dosregs.es:=la_e div 16;
          dosregs.ax:=$4b00;
          msdos(dosregs);
-         if (dosregs.flags and 1) <> 0 then
-           begin
-              doserror:=dosregs.ax;
-                lastdosexitcode:=0;
-              exit;
-           end
+         LoadDosError;
+         if DosError=0 then
+          begin
+            dosregs.ax:=$4d00;
+            msdos(dosregs);
+            LastDosExitCode:=DosRegs.al
+          end
          else
-           begin
-              dosregs.ax:=$4d00;
-              msdos(dosregs);
-              lastdosexitcode:=dosregs.al;
-           end;
+          LastDosExitCode:=0;
         end;
 
       { var
@@ -540,63 +505,11 @@ unit dos;
 {$endif GO32V2}
 
     function dosexitcode : word;
-
       begin
          dosexitcode:=lastdosexitcode;
       end;
 
-    function dosversion : word;
-
-      begin
-         dosregs.ax:=$3000;
-         msdos(dosregs);
-         dosversion:=dosregs.ax;
-      end;
-
-    procedure getdate(var year,month,day,dayofweek : word);
-
-      begin
-         dosregs.ax:=$2a00;
-         msdos(dosregs);
-         dayofweek:=dosregs.al;
-         year:=dosregs.cx;
-         month:=dosregs.dh;
-         day:=dosregs.dl;
-      end;
-
-    procedure setdate(year,month,day : word);
-
-      begin
-         dosregs.cx:=year;
-         dosregs.dx:=month*$100+day;
-         dosregs.ah:=$2b;
-         msdos(dosregs);
-         doserror:=dosregs.al;
-      end;
-
-    procedure gettime(var hour,minute,second,sec100 : word);
-
-      begin
-         dosregs.ah:=$2c;
-         msdos(dosregs);
-         hour:=dosregs.ch;
-         minute:=dosregs.cl;
-         second:=dosregs.dh;
-         sec100:=dosregs.dl;
-      end;
-
-    procedure settime(hour,minute,second,sec100 : word);
-
-      begin
-         dosregs.cx:=hour*$100+minute;
-         dosregs.dx:=second*$100+sec100;
-         dosregs.ah:=$2d;
-         msdos(dosregs);
-         doserror:=dosregs.al;
-      end;
-
     procedure getcbreak(var breakvalue : boolean);
-
       begin
          dosregs.ax:=$3300;
          msdos(dosregs);
@@ -604,7 +517,6 @@ unit dos;
       end;
 
     procedure setcbreak(breakvalue : boolean);
-
       begin
          dosregs.ax:=$3301;
          dosregs.dl:=ord(breakvalue);
@@ -612,7 +524,6 @@ unit dos;
       end;
 
     procedure getverify(var verify : boolean);
-
       begin
          dosregs.ah:=$54;
          msdos(dosregs);
@@ -620,27 +531,25 @@ unit dos;
       end;
 
     procedure setverify(verify : boolean);
-
       begin
          dosregs.ah:=$2e;
          dosregs.al:=ord(verify);
          msdos(dosregs);
       end;
 
-    function diskfree(drive : byte) : longint;
+{******************************************************************************
+                               --- Disk ---
+******************************************************************************}
 
+    function diskfree(drive : byte) : longint;
       begin
          dosregs.dl:=drive;
          dosregs.ah:=$36;
          msdos(dosregs);
          if dosregs.ax<>$FFFF then
-           begin
-              diskfree:=dosregs.ax;
-              diskfree:=diskfree*dosregs.bx;
-              diskfree:=diskfree*dosregs.cx;
-           end
+          diskfree:=dosregs.ax*dosregs.bx*dosregs.cx
          else
-           diskfree:=-1;
+          diskfree:=-1;
       end;
 
     function disksize(drive : byte) : longint;
@@ -650,20 +559,18 @@ unit dos;
          dosregs.ah:=$36;
          msdos(dosregs);
          if dosregs.ax<>$FFFF then
-           begin
-              disksize:=dosregs.ax;
-              disksize:=disksize*dosregs.cx;
-              disksize:=disksize*dosregs.dx;
-           end
+          disksize:=dosregs.ax*dosregs.cx*dosregs.dx
          else
-           disksize:=-1;
+          disksize:=-1;
       end;
 
-    procedure searchrec2dossearchrec(var f : searchrec);
+{******************************************************************************
+                       --- Findfirst FindNext ---
+******************************************************************************}
 
+    procedure searchrec2dossearchrec(var f : searchrec);
       var
          l,i : longint;
-
       begin
          l:=length(f.name);
          for i:=1 to 12 do
@@ -672,10 +579,8 @@ unit dos;
       end;
 
     procedure dossearchrec2searchrec(var f : searchrec);
-
       var
          l,i : longint;
-
       begin
          l:=12;
          for i:=0 to 12 do
@@ -714,8 +619,7 @@ unit dos;
            dosregs.ah:=$4e;
            msdos(dosregs);
            copyfromdos(f,sizeof(searchrec));
-           if dosregs.flags and carryflag<>0 then
-             doserror:=dosregs.ax;
+           LoadDosError;
         end;
 
 {$else GO32V2}
@@ -765,13 +669,12 @@ unit dos;
            copytodos(f,sizeof(searchrec));
            dosregs.edx:=transfer_buffer mod 16;
            dosregs.ds:=transfer_buffer div 16;
-                dosregs.ah:=$1a;
+           dosregs.ah:=$1a;
            msdos(dosregs);
-                dosregs.ah:=$4f;
+           dosregs.ah:=$4f;
            msdos(dosregs);
            copyfromdos(f,sizeof(searchrec));
-           if dosregs.flags and carryflag <> 0 then
-             doserror:=dosregs.ax;
+           LoadDosError;
         end;
 
 {$else GO32V2}
@@ -830,68 +733,22 @@ unit dos;
       end;
 {$endif go32v2}
 
-    function envcount : longint;
-
-      var
-         hp : ppchar;
-
-      begin
-         hp:=environ;
-         envcount:=0;
-         while assigned(hp^) do
-           begin
-              { not the best solution, but quite understandable }
-              inc(envcount);
-              hp:=hp+4;
-           end;
-      end;
-
-    function envstr(index : longint) : string;
-
-      var
-         hp : ppchar;
 
+    Procedure FindClose(Var f: SearchRec);
       begin
-         if (index<=0) or (index>envcount) then
-           begin
-              envstr:='';
-              exit;
-           end;
-         hp:=environ+4*(index-1);
-         envstr:=strpas(hp^);
       end;
 
-    function getenv(const envvar : string) : string;
+{******************************************************************************
+                               --- File ---
+******************************************************************************}
 
+    procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
       var
-         hs,_envvar : string;
-         eqpos,i : longint;
-
-      begin
-         _envvar:=upcase(envvar);
-         getenv:='';
-         for i:=1 to envcount do
-           begin
-              hs:=envstr(i);
-              eqpos:=pos('=',hs);
-              if copy(hs,1,eqpos-1)=_envvar then
-                begin
-                   getenv:=copy(hs,eqpos+1,length(hs)-eqpos);
-                   exit;
-                end;
-           end;
-      end;
-
-    procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;
-      var ext : extstr);
-
-      var
-         p1 : byte;
-         i : longint;
+         p1,i : longint;
       begin
          { allow slash as backslash }
          for i:=1 to length(path) do
-             if path[i]='/' then path[i]:='\';
+          if path[i]='/' then path[i]:='\';
          { get drive name }
          p1:=pos(':',path);
          if p1>0 then
@@ -924,18 +781,17 @@ unit dos;
       end;
 
     function fexpand(const path : pathstr) : pathstr;
-
        var
-          s,pa : string[79];
-          i,j : byte;
-
+         s,pa : string[79];
+         i,j  : longint;
        begin
           getdir(0,s);
           pa:=upcase(path);
           { allow slash as backslash }
           for i:=1 to length(pa) do
-             if pa[i]='/' then pa[i]:='\';
-          if (ord(pa[0])>1) and (((pa[1]>='A') and (pa[1]<='Z')) and (pa[2]=':')) then
+           if pa[i]='/' then
+            pa[i]:='\';
+          if (length(pa)>1) and (pa[1] in ['A'..'Z']) and (pa[2]=':') then
             begin
                { we must get the right directory }
                getdir(ord(pa[1])-ord('A')+1,s);
@@ -971,169 +827,195 @@ unit dos;
           fexpand:=pa;
        end;
 
-     procedure packtime(var d : datetime;var time : longint);
 
-       var
-          zs : longint;
-
-       begin
-          time:=-1980;
-          time:=time+d.year and 127;
-          time:=time shl 4;
-          time:=time+d.month;
-          time:=time shl 5;
-          time:=time+d.day;
-          time:=time shl 16;
-          zs:=d.hour;
-          zs:=zs shl 6;
-          zs:=zs+d.min;
-          zs:=zs shl 5;
-          zs:=zs+d.sec div 2;
-          time:=time+(zs and $ffff);
-       end;
-
-     procedure unpacktime (time: longint; var d: datetime);
-
-       begin
-          d.sec:=(time and 31) * 2;
-          time:=time shr 5;
-          d.min:=time and 63;
-          time:=time shr 6;
-          d.hour:=time and 31;
-          time:=time shr 5;
-          d.day:=time and 31;
-          time:=time shr 5;
-          d.month:=time and 15;
-          time:=time shr 4;
-          d.year:=time + 1980;
-       end;
+    Function FSearch(path: pathstr; dirlist: string): pathstr;
+      var
+         i,p1   : longint;
+         s      : searchrec;
+         newdir : pathstr;
+      begin
+      { No wildcards allowed in these things }
+         if (pos('?',path)<>0) or (pos('*',path)<>0) then
+           fsearch:=''
+         else
+           begin
+              { allow slash as backslash }
+              for i:=1 to length(dirlist) do
+                if dirlist[i]='/' then dirlist[i]:='\';
+              repeat
+                p1:=pos(';',dirlist);
+                if p1=0 then
+                 begin
+                   newdir:=copy(dirlist,1,p1-1);
+                   delete(dirlist,1,p1);
+                 end
+                else
+                 begin
+                   newdir:=dirlist;
+                   dirlist:='';
+                 end;
+                if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
+                 newdir:=newdir+'\';
+                findfirst(newdir+path,anyfile,s);
+                if doserror=0 then
+                 newdir:=newdir+path
+                else
+                 newdir:='';
+              until (dirlist='') or (newdir<>'');
+              fsearch:=newdir;
+           end;
+      end;
 
 {$ifdef GO32V2}
 
-    procedure getfattr(var f;var attr : word);
+    procedure getftime(var f;var time : longint);
+      begin
+         dosregs.bx:=textrec(f).handle;
+         dosregs.ax:=$5700;
+         msdos(dosregs);
+         time:=(dosregs.dx shl 16)+dosregs.cx;
+         doserror:=dosregs.al;
+      end;
 
-      var
-         r : registers;
+   procedure setftime(var f;time : longint);
+      begin
+         dosregs.bx:=textrec(f).handle;
+         dosregs.cx:=time and $ffff;
+         dosregs.dx:=time shr 16;
+         dosregs.ax:=$5701;
+         msdos(dosregs);
+         doserror:=dosregs.al;
+      end;
 
+    procedure getfattr(var f;var attr : word);
       begin
          copytodos(filerec(f).name,strlen(filerec(f).name)+1);
-         r.ax:=$4300;
-         r.edx:=transfer_buffer mod 16;
-         r.ds:=transfer_buffer div 16;
-         msdos(r);
-         if (r.flags and carryflag) <> 0 then
-           doserror:=r.ax;
-         attr:=r.cx;
+         dosregs.ax:=$4300;
+         dosregs.edx:=transfer_buffer and 15;
+         dosregs.ds:=transfer_buffer shr 4;
+         msdos(dosregs);
+         LoadDosError;
+         Attr:=dosregs.cx;
       end;
 
     procedure setfattr(var f;attr : word);
-
-      var
-         r : registers;
-
       begin
          copytodos(filerec(f).name,strlen(filerec(f).name)+1);
-         r.ax:=$4301;
-         r.edx:=transfer_buffer mod 16;
-         r.ds:=transfer_buffer div 16;
-         r.cx:=attr;
-         msdos(r);
-         if (r.flags and carryflag) <> 0 then
-           doserror:=r.ax;
+         dosregs.ax:=$4301;
+         dosregs.edx:=transfer_buffer mod 16;
+         dosregs.ds:=transfer_buffer div 16;
+         dosregs.cx:=attr;
+         msdos(dosregs);
+         LoadDosError;
       end;
 
 {$else GO32V2}
 
     procedure getfattr(var f;var attr : word);
-
       var
-         { to avoid problems }
          n : array[0..255] of char;
          r : registers;
-
       begin
          strpcopy(n,filerec(f).name);
-         r.ax:=$4300;
-         r.edx:=longint(@n);
-         msdos(r);
-         attr:=r.cx;
+         dosregs.ax:=$4300;
+         dosregs.edx:=longint(@n);
+         msdos(dosregs);
+         LoadDosError;
+         attr:=dosregs.cx;
       end;
 
     procedure setfattr(var f;attr : word);
-
       var
-         { to avoid problems }
          n : array[0..255] of char;
          r : registers;
-
       begin
          strpcopy(n,filerec(f).name);
-         r.ax:=$4301;
-         r.edx:=longint(@n);
-         r.cx:=attr;
-         msdos(r);
+         dosregs.ax:=$4301;
+         dosregs.edx:=longint(@n);
+         dosregs.cx:=attr;
+         msdos(dosregs);
+         LoadDosError;
       end;
 
 {$endif GO32V2}
 
-end.
 
+{******************************************************************************
+                             --- Environment ---
+******************************************************************************}
+
+    function envcount : longint;
+    var
+      hp : ppchar;
+    begin
+      hp:=envp;
+      envcount:=0;
+      while assigned(hp^) do
+       begin
+         inc(envcount);
+         hp:=hp+4;
+       end;
+    end;
+
+
+    function envstr(index : integer) : string;
+    begin
+      if (index<=0) or (index>envcount) then
+       begin
+         envstr:='';
+         exit;
+       end;
+      envstr:=strpas(ppchar(envp+4*(index-1))^);
+    end;
+
+
+    Function  GetEnv(envvar: string): string;
+    var
+      hp      : ppchar;
+      hs    : string;
+      eqpos : longint;
+    begin
+      envvar:=upcase(envvar);
+      hp:=envp;
+      getenv:='';
+      while assigned(hp^) do
+       begin
+         hs:=strpas(hp^);
+         eqpos:=pos('=',hs);
+         if copy(hs,1,eqpos-1)=envvar then
+          begin
+            getenv:=copy(hs,eqpos+1,255);
+            exit;
+          end;
+         hp:=hp+4;
+       end;
+    end;
+
+{******************************************************************************
+                             --- Not Supported ---
+******************************************************************************}
+
+Procedure keep(exitcode : word);
+Begin
+End;
+
+Procedure getintvec(intno : byte;var vector : pointer);
+Begin
+End;
+
+Procedure setintvec(intno : byte;vector : pointer);
+Begin
+End;
+
+
+end.
 {
   $Log$
-  Revision 1.2  1998-03-26 12:23:49  peter
-    * envrion is now the same for go32v1 and go32v2
-
-  Revision 1.1.1.1  1998/03/25 11:18:41  root
-  * Restored version
-
-  Revision 1.10  1998/03/12 04:02:32  carl
-    * bugfix of Range Check error in FExpand
-
-  Revision 1.9  1998/02/05 12:08:48  pierre
-    * added packrecords to about dword alignment
-      for structures used in dos calls
-
-  Revision 1.8  1998/02/03 15:52:41  pierre
-    * swapvectors really disable exception handling
-      and interrupt redirection with go32v2
-    * in dos.pp bug if arg path from fsearch had a directory part fixed
-
-  Revision 1.7  1998/01/26 11:56:22  michael
-  + Added log at the end
-
-
-
-  Working file: rtl/dos/dos.pp
-  description:
-  ----------------------------
-  revision 1.6
-  date: 1998/01/16 00:04:58;  author: michael;  state: Exp;  lines: +17 -18
-  Added some fixes of Peter Vreman
-  ----------------------------
-  revision 1.5
-  date: 1997/12/22 10:22:05;  author: pierre;  state: Exp;  lines: +2 -2
-    * bug in disksize corrected (thanks to Papai Andras)
-  ----------------------------
-  revision 1.4
-  date: 1997/12/12 13:17:15;  author: florian;  state: Exp;  lines: +3 -2
-  dos.doserror wasn't set to zero in dos.exec (go32v2)
-  ----------------------------
-  revision 1.3
-  date: 1997/12/01 12:15:45;  author: michael;  state: Exp;  lines: +12 -5
-  + added copyright reference in header.
-  ----------------------------
-  revision 1.2
-  date: 1997/11/27 22:49:03;  author: florian;  state: Exp;  lines: +6 -5
-  - CPU.PP added
-  - some bugs in DOS fixed (espsecially for go32v1)
-  - the win32 system unit is now compilable
-  ----------------------------
-  revision 1.1
-  date: 1997/11/27 08:33:49;  author: michael;  state: Exp;
-  Initial revision
-  ----------------------------
-  revision 1.1.1.1
-  date: 1997/11/27 08:33:49;  author: michael;  state: Exp;  lines: +0 -0
-  FPC RTL CVS start
-  =============================================================================
+  Revision 1.3  1998-05-21 19:30:47  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
 }
+

+ 18 - 6
rtl/dos/go32v2/emu387.pp

@@ -29,7 +29,7 @@ unit emu387;
 
   implementation
 
-    uses dxeload, dpmiexcp, strings;
+    uses dxeload, dpmiexcp;
 
   type
      emu_entry_type = function(exc : pexception_state) : longint;
@@ -123,10 +123,10 @@ unit emu387;
       hp      : ppchar;
       hs,
       _envvar : string;
-      eqpos,i : longint;
+      eqpos   : longint;
     begin
       _envvar:=upcase(envvar);
-      hp:=environ;
+      hp:=envp;
       getenv:='';
       while assigned(hp^) do
        begin
@@ -147,7 +147,7 @@ unit emu387;
        cp : string;
        i : byte;
        have_80387 : boolean;
-       emu_p : pointer; 
+       emu_p : pointer;
     const
        veryfirst : boolean = True;
 
@@ -217,7 +217,13 @@ end.
 
 {
   $Log$
-  Revision 1.3  1998-03-31 10:18:55  florian
+  Revision 1.4  1998-05-21 19:30:51  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.3  1998/03/31 10:18:55  florian
     * exit message removed
 
   Revision 1.2  1998/03/26 12:23:17  peter
@@ -254,7 +260,13 @@ end.
 
 {
   $Log$
-  Revision 1.3  1998-03-31 10:18:55  florian
+  Revision 1.4  1998-05-21 19:30:51  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.3  1998/03/31 10:18:55  florian
     * exit message removed
 
   Revision 1.2  1998/03/26 12:23:17  peter

+ 192 - 214
rtl/dos/go32v2/system.pp

@@ -17,33 +17,46 @@ unit system;
 
 {$I os.inc}
 
-  interface
+interface
 
-    { include system-independent routine headers }
+{ include system-independent routine headers }
 
-    {$I systemh.inc}
+{$I systemh.inc}
 
-    {$I heaph.inc}
+{ include heap support headers }
 
-    const 
-       seg0040 = $0040;
-       segA000 = $A000;
-       segB000 = $B000;
-       segB800 = $B800;
-
-    var
-       mem  : array[0..$7fffffff] of byte absolute $0;
-       memw : array[0..$7fffffff] of word absolute $0;
-       meml : array[0..$7fffffff] of longint absolute $0;
+{$I heaph.inc}
 
 const
-  UnusedHandle=$ffff;
-  StdInputHandle=0;
-  StdOutputHandle=1;
-  StdErrorHandle=2;
+{ Default filehandles }
+  UnusedHandle    = $ffff;
+  StdInputHandle  = 0;
+  StdOutputHandle = 1;
+  StdErrorHandle  = 2;
+
+{ Default memory segments (Tp7 compatibility) }
+  seg0040 = $0040;
+  segA000 = $A000;
+  segB000 = $B000;
+  segB800 = $B800;
+
+var
+{ Mem[] support }
+  mem  : array[0..$7fffffff] of byte absolute $0;
+  memw : array[0..$7fffffff] of word absolute $0;
+  meml : array[0..$7fffffff] of longint absolute $0;
+{ C-compatible arguments and environment }
+  argc  : longint;
+  argv  : ppchar;
+  envp  : ppchar;
+  dos_argv0 : pchar;
+{ System info }
+  Win95 : boolean;
 
 type
-       t_stub_info   = record
+{ Dos Extender info }
+  p_stub_info = ^t_stub_info;
+  t_stub_info = packed record
        magic         : array[0..15] of char;
        size          : longint;
        minstack      : longint;
@@ -58,146 +71,125 @@ type
        basename      : array[0..7] of char;
        argv0         : array [0..15] of char;
        dpmi_server   : array [0..15] of char;
-       end;
-       p_stub_info   = ^t_stub_info;
-
-    var    stub_info : p_stub_info;
+  end;
 
-{$PACKRECORDS 1}
-type
-       t_go32_info_block = record
-       size_of_this_structure_in_bytes : longint; {offset 0}
-       linear_address_of_primary_screen : longint; {offset 4}
+  p_go32_info_block = ^t_go32_info_block;
+  t_go32_info_block = packed record
+       size_of_this_structure_in_bytes    : longint; {offset 0}
+       linear_address_of_primary_screen   : longint; {offset 4}
        linear_address_of_secondary_screen : longint; {offset 8}
-       linear_address_of_transfer_buffer : longint; {offset 12}
-       size_of_transfer_buffer : longint; {offset 16}
-       pid : longint; {offset 20}
-       master_interrupt_controller_base : byte; {offset 24}
-       slave_interrupt_controller_base : byte; {offset 25}
-       selector_for_linear_memory : word; {offset 26}
+       linear_address_of_transfer_buffer  : longint; {offset 12}
+       size_of_transfer_buffer            : longint; {offset 16}
+       pid                                : longint; {offset 20}
+       master_interrupt_controller_base   : byte; {offset 24}
+       slave_interrupt_controller_base    : byte; {offset 25}
+       selector_for_linear_memory         : word; {offset 26}
        linear_address_of_stub_info_structure : longint; {offset 28}
-       linear_address_of_original_psp : longint; {offset 32}
-       run_mode : word; {offset 36}
-       run_mode_info : word; {offset 38}
-       end;
+       linear_address_of_original_psp     : longint; {offset 32}
+       run_mode                           : word; {offset 36}
+       run_mode_info                      : word; {offset 38}
+  end;
 
-var go32_info_block : t_go32_info_block;
+var
+  stub_info       : p_stub_info;
+  go32_info_block : t_go32_info_block;
 
-    type
-       trealregs=record
-          realedi,realesi,realebp,realres,
-          realebx,realedx,realecx,realeax : longint;
-          realflags,
-          reales,realds,realfs,realgs,
-          realip,realcs,realsp,realss : word;
-       end;
-    var
-       dos_argv0 : pchar;
-       environ : ppchar;
-       { Running under Win95 ? }
-       Win95 : boolean;
-
-    function do_write(h,addr,len : longint) : longint;
-    function do_read(h,addr,len : longint) : longint;
-    procedure syscopyfromdos(addr : longint; len : longint);
-    procedure syscopytodos(addr : longint; len : longint);
-    function tb : longint;
-    procedure sysrealintr(intnr : word;var regs : trealregs);
 
-  implementation
+{
+  necessary for objects.pas, should be removed (at least from the interface
+  to the implementation)
+}
+  type
+    trealregs=record
+      realedi,realesi,realebp,realres,
+      realebx,realedx,realecx,realeax : longint;
+      realflags,
+      reales,realds,realfs,realgs,
+      realip,realcs,realsp,realss  : word;
+    end;
+  function  do_write(h,addr,len : longint) : longint;
+  function  do_read(h,addr,len : longint) : longint;
+  procedure syscopyfromdos(addr : longint; len : longint);
+  procedure syscopytodos(addr : longint; len : longint);
+  procedure sysrealintr(intnr : word;var regs : trealregs);
+  function  tb : longint;
 
-    { include system independent routines }
 
-    {$I system.inc}
 
-    type
-       plongint = ^longint;
+implementation
 
-    const carryflag = 1;
+{ include system independent routines }
 
-{$S-}
-    procedure st1(stack_size : longint);[public,alias: 'STACKCHECK'];
+{$I system.inc}
 
-      begin
-         { called when trying to get local stack }
-         { if the compiler directive $S is set   }
-         { this function must preserve esi !!!!  }
-         { because esi is set by the calling     }
-         { proc for methods                      }
-         { it must preserve all registers !!     }
+const
+  carryflag = 1;
 
-         asm
-            pushl %eax
-            pushl %ebx
-            movl stack_size,%ebx
-            movl %esp,%eax
-            subl %ebx,%eax
+type
+  plongint = ^longint;
+
+var
+  doscmd : string[128];  { Dos commandline copied from PSP, max is 128 chars }
+
+
+procedure int_stackcheck(stack_size:longint);[public,alias: 'STACKCHECK'];
+{
+  called when trying to get local stack if the compiler directive $S
+  is set this function must preserve esi !!!! because esi is set by
+  the calling proc for methods it must preserve all registers !!
+}
+begin
+  asm
+        pushl   %eax
+        pushl   %ebx
+        movl    stack_size,%ebx
+        movl    %esp,%eax
+        subl    %ebx,%eax
 {$ifdef SYSTEMDEBUG}
-            movl U_SYSTEM_LOWESTSTACK,%ebx
-            cmpl %eax,%ebx
-            jb   _is_not_lowest
-            movl %eax,U_SYSTEM_LOWESTSTACK
-            _is_not_lowest:
+        movl    U_SYSTEM_LOWESTSTACK,%ebx
+        cmpl    %eax,%ebx
+        jb      _is_not_lowest
+        movl    %eax,U_SYSTEM_LOWESTSTACK
+_is_not_lowest:
 {$endif SYSTEMDEBUG}
-            movl __stkbottom,%ebx
-            cmpl %eax,%ebx
-            jae  __short_on_stack
-            popl %ebx
-            popl %eax
-            leave
-            ret  $4
-            __short_on_stack:
-            { can be usefull for error recovery !! }
-            popl %ebx
-            popl %eax
-         end['EAX','EBX'];
-         RunError(202);
-         { this needs a local variable }
-         { so the function called itself !! }
-         { Writeln('low in stack ');
-         RunError(202);             }
-      end;
+        movl    __stkbottom,%ebx
+        cmpl    %eax,%ebx
+        jae     __short_on_stack
+        popl    %ebx
+        popl    %eax
+        leave
+        ret     $4
+__short_on_stack:
+        { can be usefull for error recovery !! }
+        popl    %ebx
+        popl    %eax
+  end['EAX','EBX'];
+  RunError(202);
+end;
 
-    function tb : longint;
-    begin
-    tb := go32_info_block.linear_address_of_transfer_buffer;
-    {   asm
-       leal __go32_info_block,%ebx
-       movl 12(%ebx),%eax
-       leave
-       ret
-       end ['EAX','EBX'];}
-    end;
 
-    function tb_size : longint;
-    begin
-    tb_size := go32_info_block.size_of_transfer_buffer;
-{       asm
-       leal __go32_info_block,%ebx
-       movl 16(%ebx),%eax
-       leave
-       ret
-       end ['EAX','EBX'];}
-    end;
+function tb : longint;
+begin
+  tb:=go32_info_block.linear_address_of_transfer_buffer;
+end;
 
-    function dos_selector : word;
-    begin
-       dos_selector:=go32_info_block.selector_for_linear_memory;
-{       asm
-       leal __go32_info_block,%ebx
-       movw 26(%ebx),%ax
-       movw %ax,__RESULT
-       end ['EAX','EBX'];}
-    end;
 
-    function get_ds : word;
+function tb_size : longint;
+begin
+  tb_size:=go32_info_block.size_of_transfer_buffer;
+end;
 
-      begin
-         asm
-            movw %ds,%ax
-            movw %ax,__RESULT;
-         end;
-      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;
 
 
     procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
@@ -268,13 +260,6 @@ var go32_info_block : t_go32_info_block;
            end ['ESI','EDI','ECX'];
       end;
 
-
-{ included directly old file sargs.inc }
-
-var argc : longint;
-    doscmd : string;
-    args : ppchar;
-
 function far_strlen(selector : word;linear_address : longint) : longint;
 begin
 asm
@@ -294,6 +279,7 @@ asm
 end;
 end;
 
+
 function atohex(s : pchar) : longint;
 var rv : longint;
     v : byte;
@@ -316,7 +302,7 @@ var psp : word;
     i,j : byte;
     quote : char;
     proxy_s : string[7];
-    tempargs : ppchar;
+    tempargv : ppchar;
     al,proxy_argc,proxy_seg,proxy_ofs,lin : longint;
     largs : array[0..127] of pchar;
     rm_argv : ^arrayword;
@@ -394,16 +380,17 @@ if (argc > 1) and (far_strlen(get_ds,longint(largs[1])) = 6)  then
     argc := proxy_argc;
     end;
   end;
-getmem(args,argc*SizeOf(pchar));
+getmem(argv,argc shl 2);
 for i := 0 to argc-1  do
-   args[i] := largs[i];
-  tempargs:=args;
+   argv[i] := largs[i];
+  tempargv:=argv;
   asm
-     movl tempargs,%eax
+     movl tempargv,%eax
      movl %eax,_args
   end;
 end;
 
+
 function strcopy(dest,source : pchar) : pchar;
 
       begin
@@ -454,36 +441,37 @@ begin
     while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
     inc(longint(cp)); { skip to next character }
     end;
-  getmem(environ,(env_count+1) * sizeof(pchar));
-  if (environ = nil) then exit;
+  getmem(envp,(env_count+1) * sizeof(pchar));
+  if (envp = nil) then exit;
   cp:=dos_env;
   env_count:=0;
   while cp^ <> #0 do
     begin
-    getmem(environ[env_count],strlen(cp)+1);
-    strcopy(environ[env_count], cp);
+    getmem(envp[env_count],strlen(cp)+1);
+    strcopy(envp[env_count], cp);
 {$IfDef SYSTEMDEBUG}
-      Writeln('env ',env_count,' = "',environ[env_count],'"');
+      Writeln('env ',env_count,' = "',envp[env_count],'"');
 {$EndIf SYSTEMDEBUG}
     inc(env_count);
     while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
     inc(longint(cp)); { skip to next character }
     end;
-  environ[env_count]:=nil;
+  envp[env_count]:=nil;
   inc(longint(cp),3);
   getmem(dos_argv0,strlen(cp)+1);
   if (dos_argv0 = nil) then halt;
   strcopy(dos_argv0, cp);
 end;
+
      procedure syscopytodos(addr : longint; len : longint);
      begin
-        if len > tb_size then runerror(200);
+        if len > tb_size then runerror(217);
         sysseg_move(get_ds,addr,dos_selector,tb,len);
      end;
 
      procedure syscopyfromdos(addr : longint; len : longint);
      begin
-        if len > tb_size then runerror(200);
+        if len > tb_size then runerror(217);
         sysseg_move(dos_selector,tb,get_ds,addr,len);
      end;
 
@@ -496,8 +484,6 @@ end;
             movw  intnr,%bx
             xorl  %ecx,%ecx
             movl  regs,%edi
-
-            // es is always equal ds
             movw  $0x300,%ax
             int   $0x31
          end;
@@ -519,60 +505,47 @@ end;
          end;
       end;
 
-    function paramcount : longint;
-
-      begin
-      paramcount := argc - 1;
-      {   asm
-            movl _argc,%eax
-            decl %eax
-            leave
-            ret
-         end ['EAX'];}
-      end;
-
-    function paramstr(l : longint) : string;
+function paramcount : longint;
+begin
+  paramcount := argc - 1;
+end;
 
-      var
-         p : ^pchar;
 
-      begin
-         if (l>=0) and (l<=paramcount) then
-           begin
-              p:=args;
-              paramstr:=strpas(p[l]);
-           end
-         else paramstr:='';
-      end;
-
-    procedure randomize;
+function paramstr(l : longint) : string;
+begin
+  if (l>=0) and (l+1<=argc) then
+   paramstr:=strpas(argv[l])
+  else
+   paramstr:='';
+end;
 
-      var
-         hl : longint;
-         regs : trealregs;
 
-      begin
-         regs.realeax:=$2c00;
-         sysrealintr($21,regs);
-         hl:=regs.realedx and $ffff;
-         randseed:=hl*$10000+ (regs.realecx and $ffff);
-      end;
+procedure randomize;
+var
+  hl   : longint;
+  regs : trealregs;
+begin
+  regs.realeax:=$2c00;
+  sysrealintr($21,regs);
+  hl:=regs.realedx and $ffff;
+  randseed:=hl*$10000+ (regs.realecx and $ffff);
+end;
 
-{ use standard heap management }
+{*****************************************************************************
+                              Heap Management
+*****************************************************************************}
 
-  function Sbrk(size : longint) : longint;
+function Sbrk(size : longint):longint;assembler;
+asm
+        movl    size,%eax
+        pushl   %eax
+        call    ___sbrk
+        addl    $4,%esp
+end;
 
-    begin
-       asm
-         movl size,%eax
-         pushl %eax
-         call ___sbrk
-         addl $4,%esp
-         movl %eax,__RESULT
-       end;
-    end;
+{ include standard heap management }
+{$I heap.inc}
 
-{$i heap.inc}
 
 {****************************************************************************
                         Low level File Routines
@@ -768,7 +741,6 @@ begin
 end;
 
 
-
 function do_filesize(handle : longint) : longint;
 var
   aktfilepos : longint;
@@ -960,7 +932,7 @@ begin
    end
   else
    syscopyfromdos(longint(@temp),251);
-{ conversation to Pascal string }
+{ conversation to Pascal string including slash conversion }
   i:=0;
   while (temp[i]<>#0) do
    begin
@@ -972,7 +944,7 @@ begin
   dir[2]:=':';
   dir[3]:='\';
   dir[0]:=chr(i+3);
-{ upcase the string (FPKPascal function) }
+{ upcase the string }
   dir:=upcase(dir);
   if drivenr<>0 then   { Drive was supplied. We know it }
    dir[1]:=chr(65+drivenr-1)
@@ -999,7 +971,7 @@ begin
   regs.realeax:=$160a;
   sysrealintr($2f,regs);
   CheckWin95:=(regs.realeax=0) and ((regs.realebx and $ff00)=$400);
-end;  
+end;
 
 
 procedure OpenStdIO(var f:text;mode:word;hdl:longint);
@@ -1012,7 +984,7 @@ begin
   TextRec(f).Closefunc:=@fileclosefunc;
 end;
 
-     
+
 Begin
 { Initialize ExitProc }
   ExitProc:=Nil;
@@ -1029,12 +1001,18 @@ Begin
   Setup_Arguments;
 { Use Win95 LFN }
   Win95:=CheckWin95;
-{ Reset IO Error }  
+{ Reset IO Error }
   InOutRes:=0;
 End.
 {
   $Log$
-  Revision 1.4  1998-05-04 17:58:41  peter
+  Revision 1.5  1998-05-21 19:30:52  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.4  1998/05/04 17:58:41  peter
     * fix for smartlinking with _ARGS
 
   Revision 1.3  1998/05/04 16:21:54  florian

+ 48 - 8
rtl/inc/file.inc

@@ -31,6 +31,24 @@ Begin
 End;
 
 
+Procedure assign(var f:File;p:pchar);
+{
+  Assign Name to file f so it can be used with the file routines
+}
+begin
+  Assign(f,StrPas(p));
+end;
+
+
+Procedure assign(var f:File;c:char);
+{
+  Assign Name to file f so it can be used with the file routines
+}
+begin
+  Assign(f,string(c));
+end;
+
+
 Procedure Rewrite(var f:File;l:Word);[IOCheck];
 {
   Create file f with recordsize of l
@@ -242,22 +260,44 @@ Begin
 End;
 
 
-Procedure Rename(var f : File;const s : string);[IOCheck];
-var
-  p : array[0..255] Of Char;
+Procedure Rename(var f : File;p:pchar);[IOCheck];
 Begin
   If FileRec(f).mode=fmClosed Then
    Begin
-     Move(s[1],p,Length(s));
-     p[Length(s)]:=#0;
-     Do_Rename(PChar(@FileRec(f).Name),PChar(@p));
-     Move(p,FileRec(f).Name,Length(s)+1);
+     Do_Rename(PChar(@FileRec(f).Name),p);
+     Move(p,FileRec(f).Name,StrLen(p)+1);
    End;
 End;
 
+
+Procedure Rename(var f : File;const s : string);[IOCheck];
+var
+  p : array[0..255] Of Char;
+Begin
+  Move(s[1],p,Length(s));
+  p[Length(s)]:=#0;
+  Rename(f,Pchar(@p));
+End;
+
+
+Procedure Rename(var f : File;c : char);[IOCheck];
+var
+  p : array[0..1] Of Char;
+Begin
+  p[0]:=c;
+  p[1]:=#0;
+  Rename(f,Pchar(@p));
+End;
+
 {
   $Log$
-  Revision 1.2  1998-05-12 10:42:44  peter
+  Revision 1.3  1998-05-21 19:30:56  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.2  1998/05/12 10:42:44  peter
     * moved getopts to inc/, all supported OS's need argc,argv exported
     + strpas, strlen are now exported in the systemunit
     * removed logs

+ 22 - 56
rtl/inc/getopts.pp

@@ -6,7 +6,6 @@
 
     Getopt implementation for Free Pascal, modeled after GNU getopt.
 
-
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
 
@@ -17,8 +16,6 @@
  **********************************************************************}
 unit getopts;
 
-{$I os.inc}
-
 { --------------------------------------------------------------------
   *NOTE*
   The routines are a more or less straightforward conversion
@@ -33,16 +30,14 @@ Interface
 Const No_Argument       = 0;
       Required_Argument = 1;
       Optional_Argument = 2;
-
       EndOfOptions      = #255;
 
-
 Type TOption = Record
        Name    : String;
        Has_arg : Integer;
        Flag    : PChar;
        Value   : Char;
-      end;
+     end;
      POption  = ^TOption;
      Orderings = (require_order,permute,return_in_order);
 
@@ -51,13 +46,8 @@ Var OptArg : String;
     OptErr : Boolean;
     OptOpt : Char;
 
-
 Function GetOpt (ShortOpts : String) : char;
-Function GetLongOpts (ShortOpts : String;
-
-                      LongOpts : POption;
-
-                      var Longind : Integer) : char;
+Function GetLongOpts (ShortOpts : String;LongOpts : POption;var Longind : Integer) : char;
 
 Implementation
 
@@ -68,8 +58,6 @@ Var
   last_nonopt   : Longint;
   Ordering      : Orderings;
 
-
-
 Procedure Exchange;
 var
   bottom,
@@ -120,28 +108,26 @@ begin
   OptOpt:='?';
   Nextchar:=0;
   if opts[1]='-' then
-
-    begin
-    ordering:=return_in_order;
-    delete(opts,1,1);
-    end
-  else if opts[1]='+' then
+   begin
+     ordering:=return_in_order;
+     delete(opts,1,1);
+   end
+  else
+   if opts[1]='+' then
     begin
-    ordering:=require_order;
-    delete(opts,1,1);
+      ordering:=require_order;
+      delete(opts,1,1);
     end
-  else ordering:=permute;
+  else
+   ordering:=permute;
 end;
 
 
 
-Function Internal_getopt (Var Optstring : string;
-                          LongOpts : POption;
-                          LongInd : pointer;
-                          Long_only : boolean ) : char;
+Function Internal_getopt (Var Optstring : string;LongOpts : POption;
+                          LongInd : pointer;Long_only : boolean ) : char;
 type
   pinteger=^integer;
-
 var
   temp,endopt,option_index : byte;
   indfound: integer;
@@ -149,7 +135,6 @@ var
   p,pfound : POption;
   exact,ambig : boolean;
   c : char;
-
 begin
   optarg:='';
   if optind=0 then
@@ -157,7 +142,6 @@ begin
 { Check if We need the next argument. }
   if optind<nrargs then currentarg:=strpas(argv[optind]) else currentarg:='';
   if (nextchar=0) then
-
    begin
      if ordering=permute then
       begin
@@ -183,13 +167,11 @@ begin
         if (first_nonopt<>last_nonopt) and (last_nonopt<>optind) then
          exchange
         else
-
          if first_nonopt=last_nonopt then
           first_nonopt:=optind;
         last_nonopt:=nrargs;
         optind:=nrargs;
       end;
-
    { Are we at the end of all arguments ? }
      if optind>=nrargs then
       begin
@@ -226,7 +208,6 @@ begin
    end;
 { Check if we have a long option }
   if longopts<>nil then
-
    if length(currentarg)>1 then
     if (currentarg[2]='-') or
        ((not long_only) and (pos(currentarg[2],optstring)<>0)) then
@@ -266,7 +247,6 @@ begin
           inc (option_index);
         end;
        if ambig and not exact then
-
         begin
           if opterr then
            writeln (paramstr(0),': option "',optname,'" is ambiguous');
@@ -287,16 +267,13 @@ begin
                  if currentarg[2]='-' then
                   writeln (paramstr(0),': option "--',pfound^.name,'" doesn''t allow an argument')
                  else
-
                   writeln (paramstr(0),': option "',currentarg[1],pfound^.name,'" doesn''t allow an argument');
                 nextchar:=0;
                 internal_getopt:='?';
                 exit;
               end;
            end
-
           else { argument in next paramstr...  }
-
            begin
              if pfound^.has_arg=1 then
               begin
@@ -317,13 +294,11 @@ begin
                    exit;
                  end;
               end;
-
           end; { argument in next parameter end;}
          nextchar:=0;
          if longind<>nil then
           pinteger(longind)^:=indfound+1;
             if pfound^.flag<>nil then
-
             begin
               pfound^.flag^:=pfound^.value;
               internal_getopt:=#0;
@@ -346,14 +321,12 @@ begin
            Internal_getopt:='?';
            exit;
         end;
-
      end; { Of long options.}
 { We check for a short option. }
   temp:=pos(currentarg[nextchar],optstring);
   c:=currentarg[nextchar];
   inc(nextchar);
   if nextchar>length(currentarg) then
-
    begin
      inc(optind);
      nextchar:=0;
@@ -368,7 +341,6 @@ begin
    end;
   Internal_getopt:=optstring[temp];
   if optstring[temp+1]=':' then
-
    if currentarg[temp+2]=':' then
     begin { optional argument }
       optarg:=copy (currentarg,nextchar,length(currentarg)-nextchar+1);
@@ -377,7 +349,6 @@ begin
    else
     begin { required argument }
       if nextchar>0 then
-
        begin
          optarg:=copy (currentarg,nextchar,length(currentarg)-nextchar+1);
          inc(optind)
@@ -389,11 +360,9 @@ begin
            writeln (paramstr(0),': option requires an argument -- ',optstring[temp]);
           optopt:=optstring[temp];
           if optstring[1]=':' then
-
            Internal_getopt:=':'
           else
            Internal_Getopt:='?'
-
         end
        else
         begin
@@ -411,31 +380,28 @@ begin
 end;
 
 
-Function GetLongOpts(ShortOpts : String;
-
-                     LongOpts : POption;
-
-                     var Longind : Integer) : char;
+Function GetLongOpts (ShortOpts : String;LongOpts : POption;var Longind : Integer) : char;
 begin
   getlongopts:=internal_getopt ( shortopts,longopts,@longind,true);
 end;
 
 
-
-
 begin
 { Needed to detect startup }
-
   Opterr:=true;
   Optind:=0;
   nrargs:=paramcount+1;
 end.
 
-
-
 {
   $Log$
-  Revision 1.1  1998-05-12 10:42:45  peter
+  Revision 1.2  1998-05-21 19:30:57  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.1  1998/05/12 10:42:45  peter
     * moved getopts to inc/, all supported OS's need argc,argv exported
     + strpas, strlen are now exported in the systemunit
     * removed logs

+ 23 - 6
rtl/inc/objects.pp

@@ -1,3 +1,6 @@
+{
+  $Id$
+}
 {************[ SOURCE FILE OF FREE VISION ]****************}
 {                                                          }
 {    System independent clone of objects.pas               }
@@ -85,16 +88,20 @@ UNIT Objects;
 
 
 {==== Compiler directives ===========================================}
+{$IFNDEF FPC}
+{ FPC doesn't support these switches in 0.99.5 }
+  {$F+} { Force far calls }
+  {$A+} { Word Align Data }
+  {$B-} { Allow short circuit boolean evaluations }
+{$ENDIF}
+
 {$E+} {  Emulation is on }
 {$X+} { Extended syntax is ok }
-{$F+} { Force far calls }
-{$A+} { Word Align Data }
 {$R-} { Disable range checking }
 {$S-} { Disable Stack Checking }
 {$I-} { Disable IO Checking }
 {$Q-} { Disable Overflow Checking }
 {$V-} { Turn off strict VAR strings }
-{$B-} { Allow short circuit boolean evaluations }
 {====================================================================}
 
 {***************************************************************************}
@@ -1586,7 +1593,7 @@ END;
 {  ChangeListSize -> Platforms DOS/DPMI/WIN/OS2 - Checked 19May96 LdB       }
 {---------------------------------------------------------------------------}
 FUNCTION TMemoryStream.ChangeListSize (ALimit: Sw_Word): Boolean;
-VAR I, W: Word; Li, Ti: LongInt; P: PPointerArray;
+VAR I, W: Word; Li: LongInt; P: PPointerArray;
 BEGIN
    If (ALimit <> BlkCount) Then Begin                 { Change is needed }
      ChangeListSize := False;                         { Preset failure }
@@ -1946,7 +1953,7 @@ END;
 {---------------------------------------------------------------------------}
 PROCEDURE TCollection.Store (Var S: TStream);
 
-   PROCEDURE DoPutItem (P: Pointer); FAR;
+   PROCEDURE DoPutItem (P: Pointer);{$IFNDEF FPC}FAR;{$ENDIF}
    BEGIN
      PutItem(S, P);                                   { Put item on stream }
    END;
@@ -2018,6 +2025,7 @@ END;
 FUNCTION TSortedCollection.Compare (Key1, Key2: Pointer): Sw_Integer;
 BEGIN
    Abstract;                                          { Abstract method }
+   Compare:=0;
 END;
 
 {--TSortedCollection--------------------------------------------------------}
@@ -2409,7 +2417,7 @@ END;
 FUNCTION TResourceFile.SwitchTo (AStream: PStream; Pack: Boolean): PStream;
 VAR NewBasePos: LongInt;
 
-   PROCEDURE DoCopyResource (Item: PResourceItem); FAR;
+   PROCEDURE DoCopyResource (Item: PResourceItem);{$IFNDEF FPC}FAR;{$ENDIF}
    BEGIN
      Stream^.Seek(BasePos + Item^.Posn);              { Move stream position }
      Item^.Posn := AStream^.GetPos - NewBasePos;      { Hold new position }
@@ -2719,3 +2727,12 @@ END;
 
 
 END.
+{
+  $Log$
+  Revision 1.2  1998-05-21 19:30:58  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+}

+ 10 - 1
rtl/inc/platform.inc

@@ -1,4 +1,5 @@
 {*****************************************************************************
+    $Id$
    Include file to sort out compilers/platforms/targets
 
    Copyright (c) 1997 Balazs Scheidler ([email protected])
@@ -8,7 +9,6 @@
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
-
    This library 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.  See the GNU
@@ -120,3 +120,12 @@
 Requires Free Pascal (FPK) v0.9.2 or higher
 {$ENDIF}
 
+{
+  $Log$
+  Revision 1.2  1998-05-21 19:30:59  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+}

+ 21 - 3
rtl/inc/systemh.inc

@@ -32,7 +32,8 @@ Type
   shortint = -128..127;
   byte     = 0..255;
   Word     = 0..65535;
-  
+
+
 { at least declare Turbo Pascal real types }
 {$IFDEF i386}
   Double = real;
@@ -53,7 +54,8 @@ const
 { max. values for longint and int}
   maxLongint = $7fffffff;
   maxint = 32767;
-  
+
+
 { Compatibility With  TP }
 {$ifdef i386}
   Test8086 : byte = 2;       { Always i386 or newer }
@@ -236,6 +238,8 @@ Procedure Val(const s:string;Var v:cardinal);
 ****************************************************************************}
 
 Procedure Assign(Var f:File;const Name:string);
+Procedure Assign(Var f:File;p:pchar);
+Procedure Assign(Var f:File;c:char);
 Procedure Rewrite(Var f:File;l:Word);
 Procedure Rewrite(Var f:File);
 Procedure Reset(Var f:File;l:Word);
@@ -255,6 +259,8 @@ Procedure Seek(Var f:File;Pos:Longint);
 Function  EOF(Var f:File):Boolean;
 Procedure Erase(Var f:File);
 Procedure Rename(Var f:File;const s:string);
+Procedure Rename(Var f:File;p:pchar);
+Procedure Rename(Var f:File;c:char);
 Procedure Truncate (Var F:File);
 
 {****************************************************************************
@@ -262,6 +268,8 @@ Procedure Truncate (Var F:File);
 ****************************************************************************}
 
 Procedure Assign(Var f:TypedFile;const Name:string);
+Procedure Assign(Var f:TypedFile;p:pchar);
+Procedure Assign(Var f:TypedFile;c:char);
 Procedure Rewrite(Var f:TypedFile);
 Procedure Reset(Var f:TypedFile);
 
@@ -270,6 +278,8 @@ Procedure Reset(Var f:TypedFile);
 ****************************************************************************}
 
 Procedure Assign(Var t:Text;const s:string);
+Procedure Assign(Var t:Text;p:pchar);
+Procedure Assign(Var t:Text;c:char);
 Procedure Close(Var t:Text);
 Procedure Rewrite(Var t:Text);
 Procedure Reset(Var t:Text);
@@ -277,6 +287,8 @@ Procedure Append(Var t:Text);
 Procedure Flush(Var t:Text);
 Procedure Erase(Var t:Text);
 Procedure Rename(Var t:Text;const s:string);
+Procedure Rename(Var t:Text;p:pchar);
+Procedure Rename(Var t:Text;c:char);
 Function  EOF(Var t:Text):Boolean;
 Function  EOF:Boolean;
 Function  EOLn(Var t:Text):Boolean;
@@ -320,7 +332,13 @@ Procedure AddExitProc(Proc:TProcedure);
 
 {
   $Log$
-  Revision 1.5  1998-05-12 10:42:45  peter
+  Revision 1.6  1998-05-21 19:31:00  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.5  1998/05/12 10:42:45  peter
     * moved getopts to inc/, all supported OS's need argc,argv exported
     + strpas, strlen are now exported in the systemunit
     * removed logs

+ 77 - 10
rtl/inc/text.inc

@@ -77,6 +77,18 @@ Begin
 End;
 
 
+Procedure assign(var t:Text;p:pchar);
+begin
+  Assign(t,StrPas(p));
+end;
+
+
+Procedure assign(var t:Text;c:char);
+begin
+  Assign(t,string(c));
+end;
+
+
 Procedure Close(var t : Text);[Public,Alias: 'CLOSE_TEXT',IOCheck];
 Begin
   If (TextRec(t).mode<>fmClosed) Then
@@ -149,20 +161,36 @@ Begin
 End;
 
 
-Procedure Rename(var t:Text;const s:String);[IOCheck];
-var
-  p : array[0..255] Of Char;
+Procedure Rename(var t : text;p:pchar);[IOCheck];
 Begin
   If TextRec(t).mode=fmClosed Then
    Begin
-     Move(s[1],p,Length(s));
-     p[Length(s)]:=#0;
-     Do_Rename(PChar(@TextRec(t).Name),PChar(@p));
-     Move(p,TextRec(t).Name,Length(s)+1);
+     Do_Rename(PChar(@TextRec(t).Name),p);
+     Move(p,TextRec(t).Name,StrLen(p)+1);
    End;
 End;
 
 
+Procedure Rename(var t : Text;const s : string);[IOCheck];
+var
+  p : array[0..255] Of Char;
+Begin
+  Move(s[1],p,Length(s));
+  p[Length(s)]:=#0;
+  Rename(t,Pchar(@p));
+End;
+
+
+Procedure Rename(var t : Text;c : char);[IOCheck];
+var
+  p : array[0..1] Of Char;
+Begin
+  p[0]:=c;
+  p[1]:=#0;
+  Rename(t,Pchar(@p));
+End;
+
+
 Function Eof(Var t: Text): Boolean;[IOCheck];
 Begin
 {$IFNDEF EXTENDED_EOF}
@@ -678,8 +706,41 @@ Begin
      { copy string. }
      Move (f.Bufptr^[f.BufPos],p^,Temp-f.BufPos);
      Inc(Longint(p),Temp-f.BufPos);
-     If p^=#13 Then
-      dec(Longint(p));
+     If pchar(p-1)^=#13 Then
+      dec(p);
+     { update f.BufPos }
+     f.BufPos:=Temp;
+     If Temp>=f.BufEnd Then
+      Begin
+        FileFunc(f.InOutFunc)(f);
+        Temp:=f.BufPos;
+      End
+   End;
+  p^:=#0;
+End;
+
+
+Procedure r(var f : TextRec;var s : array00);[Public,Alias:'READ_TEXT_PCHAR_AS_ARRAY'];
+var
+  p    : PChar;
+  Temp : byte;
+Begin
+{ Delete the string }
+  s[0]:=#0;
+  p:=pchar(@s);
+  if not OpenInput(f) then
+   exit;
+  Temp:=f.BufPos;
+  while (f.BufPos<f.BufEnd) and (f.Bufptr^[Temp]<>#10) Do
+   Begin
+     { search linefeed }
+     while (f.Bufptr^[Temp]<>#10) and (Temp<f.BufEnd) Do
+      inc(Temp);
+     { copy string. }
+     Move (f.Bufptr^[f.BufPos],p^,Temp-f.BufPos);
+     Inc(Longint(p),Temp-f.BufPos);
+     If pchar(p-1)^=#13 Then
+      dec(p);
      { update f.BufPos }
      f.BufPos:=Temp;
      If Temp>=f.BufEnd Then
@@ -887,7 +948,13 @@ Begin
 End;
 {
   $Log$
-  Revision 1.5  1998-05-12 10:42:45  peter
+  Revision 1.6  1998-05-21 19:31:01  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.5  1998/05/12 10:42:45  peter
     * moved getopts to inc/, all supported OS's need argc,argv exported
     + strpas, strlen are now exported in the systemunit
     * removed logs

+ 28 - 1
rtl/inc/typefile.inc

@@ -17,6 +17,9 @@
 ****************************************************************************}
 
 Procedure assign(var f:TypedFile;const Name:string);
+{
+  Assign Name to file f so it can be used with the file routines
+}
 Begin
   FillChar(f,SizeOF(FileRec),0);
   FileRec(f).Handle:=UnusedHandle;
@@ -25,6 +28,24 @@ Begin
 End;
 
 
+Procedure assign(var f:TypedFile;p:pchar);
+{
+  Assign Name to file f so it can be used with the file routines
+}
+begin
+  Assign(f,StrPas(p));
+end;
+
+
+Procedure assign(var f:TypedFile;c:char);
+{
+  Assign Name to file f so it can be used with the file routines
+}
+begin
+  Assign(f,string(c));
+end;
+
+
 Procedure Int_Typed_Reset(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias: 'RESET_TYPED'];
 Begin
   Reset(UnTypedFile(f),Size);
@@ -54,7 +75,13 @@ End;
 
 {
   $Log$
-  Revision 1.2  1998-05-12 10:42:45  peter
+  Revision 1.3  1998-05-21 19:31:02  peter
+    * objects compiles for linux
+    + assign(pchar), assign(char), rename(pchar), rename(char)
+    * fixed read_text_as_array
+    + read_text_as_pchar which was not yet in the rtl
+
+  Revision 1.2  1998/05/12 10:42:45  peter
     * moved getopts to inc/, all supported OS's need argc,argv exported
     + strpas, strlen are now exported in the systemunit
     * removed logs

+ 3 - 1
rtl/linux/makefile

@@ -232,8 +232,10 @@ crt$(PPUEXT) : crt.pp $(INC)/textrec.inc $(INC)/filerec.inc linux$(PPUEXT)\
 	       $(SYSTEMPPU)
 	$(PP) $(OPT) crt $(REDIR)
 
-objects$(PPUEXT) : objects.pp $(SYSTEMPPU)
+objects$(PPUEXT) : $(INC)/objects.pp objinc.inc $(SYSTEMPPU)
+	$(COPY) $(INC)/objects.pp .
 	$(PP) $(OPT) objects $(REDIR)
+	$(DEL) objects.pp
 
 printer$(PPUEXT) : printer.pp $(INC)/textrec.inc linux$(PPUEXT) $(SYSTEMPPU)
 	$(PP) $(OPT) printer $(REDIR)

+ 8 - 0
rtl/linux/objinc.inc

@@ -56,12 +56,20 @@ BEGIN
 END;
 
 FUNCTION SetFileSize (Handle: THandle; FileSize: LongInt): Word;
+{$IFDEF DOSSETFILE1}  
 VAR Actual, Buf: LongInt;
+{$ENDIF}   
 BEGIN
+  if Sys_Truncate(Handle,FileSize)=0 then
+   SetFileSize:=0
+  else
+   SetFileSize:=103;
+{$IFDEF DOSSETFILE1}  
    If (Actual = FileSize) Then Begin                  { No position error }
      Actual := FileWrite(Handle, Pointer(@Buf), 0,Actual);   { Truncate the file }
      If (Actual <> -1) Then SetFileSize := 0 Else     { No truncate error }
        SetFileSize := 103;                            { File truncate error }
    End Else SetFileSize := 103;                       { File truncate error }
+{$ENDIF}   
 END;