Browse Source

* 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 27 năm trước cách đây
mục cha
commit
eb39182b3b
13 tập tin đã thay đổi với 1050 bổ sung1119 xóa
  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;