From 77dd315869bbcbcdafbd7e32f1f78a92cd9b5a46 Mon Sep 17 00:00:00 2001
From: marco <marco@freepascal.org>
Date: Wed, 2 Feb 2000 15:41:56 +0000
Subject: [PATCH]  * Initial BSD version. Still needs a lot of work.

---
 rtl/bsd/syscalls.inc | 387 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 387 insertions(+)
 create mode 100644 rtl/bsd/syscalls.inc

diff --git a/rtl/bsd/syscalls.inc b/rtl/bsd/syscalls.inc
new file mode 100644
index 0000000000..4756fc3309
--- /dev/null
+++ b/rtl/bsd/syscalls.inc
@@ -0,0 +1,387 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Michael Van Canneyt,
+    member of the Free Pascal development team.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{BSD version of the syscalls required to implement SysLinux.}
+
+{No debugging for syslinux include !}
+{$IFDEF SYS_LINUX}
+  {$UNDEF SYSCALL_DEBUG}
+{$ENDIF SYS_LINUX}  
+
+{*****************************************************************************
+                     --- Main:The System Call Self ---
+*****************************************************************************}
+
+{ The system designed for Linux can't be used for FreeBSD so easily, since 
+  FreeBSD pushes arguments, instead of loading them to registers.
+
+For now I do them in assembler, which makes it easier to test them (copy and
+paste to and AS source). Ultimately I hope to design something like this}
+
+{
+Function SysCall( callnr:longint;var regs : SysCallregs ):longint;
+{
+  This function serves as an interface to do_SysCall.
+  If the SysCall returned a negative number, it returns -1, and puts the
+  SysCall result in errno. Otherwise, it returns the SysCall return value
+}
+begin
+  do_SysCall(callnr,regs);
+  if regs.reg1<0 then
+   begin
+{$IFDEF SYSCALL_DEBUG}
+     If DoSysCallDebug then
+       debugtxt:=' syscall error: ';
+{$endif}
+     ErrNo:=-regs.reg1;
+     SysCall:=-1;
+   end
+  else
+   begin
+{$IFDEF SYSCALL_DEBUG}
+  if DoSysCallDebug then
+       debugtxt:=' syscall returned: ';
+{$endif}
+     SysCall:=regs.reg1;
+     errno:=0
+   end;
+{$IFDEF SYSCALL_DEBUG}
+  if DoSysCallDebug then
+    begin
+    inc(lastcnt);
+    if (callnr<>lastcall) or (regs.reg1<>lasteax) then
+      begin
+      if lastcnt>1 then
+        writeln(sys_nr_txt[lastcall],debugtxt,lasteax,' (',lastcnt,'x)');
+      lastcall:=callnr;
+      lasteax:=regs.reg1;
+      lastcnt:=0;
+      writeln(sys_nr_txt[lastcall],debugtxt,lasteax);
+      end;
+    end;     
+{$endif}
+end;
+}
+
+{$PACKRECORDS C}
+
+TYPE timeval=RECORD
+	      tv_sec,
+	      tv_used : int64;
+	      END;
+    timezone=RECORD
+	      tz_minuteswest,
+	      tz_dsttime   : LONGINT;
+              END;
+
+
+function checkreturnvalue(retval:LONGINT;value:LONGINT):LONGINT;
+
+begin
+ if retval<0 THEN
+   begin
+     errno:=-retval;
+     checkreturnvalue:=-1;
+   end
+  else
+   begin
+     checkreturnvalue:=value;
+     errno:=0
+   end;
+end;
+
+Function Sys_Time:longint;
+
+VAR tv : timeval;
+    tz : timezone;
+    retval : longint;
+begin
+  asm
+   lea   tv,%ebx
+   pushl %ebx
+   lea   tz,%ecx
+   pushl %ecx
+   mov   $116,%eax
+   int   $0x80
+   add   $8,%esp
+   mov   %eax,retval
+  end;
+  
+ sys_time:=checkreturnvalue(retval,tv.tv_sec);
+end;
+
+{*****************************************************************************
+               --- File:File handling related calls ---
+*****************************************************************************}
+
+
+Function Sys_Open(f:pchar;flags:longint;mode:integer):longint;
+
+var retval: LONGINT;
+
+Begin
+ asm 
+   pushl mode
+   pushl flags
+   pushl f
+   movl  $5,%eax
+   int   $0x80
+   add   $12,%esp
+   mov   %eax,retval
+  end;
+ sys_open:=checkreturnvalue(retval,retval);
+End;
+
+Function Sys_Close(f:longint):longint;
+
+var retval: LONGINT;
+
+begin
+ asm 
+   pushl f
+   movl  $6,%eax
+   int   $0x80
+   addl  $4,%esp
+   mov   %eax,retval
+ end;
+ Sys_Close:=checkreturnvalue(retval,retval);
+end;
+
+Function Sys_Lseek(F:longint;Off:longint;Whence:longint):longint;
+
+var retval: LONGINT;
+
+begin
+  asm
+    pushl Whence
+    pushl Off
+    pushl F
+    mov   $199,%eax
+    int   $0x80
+    addl  $12,%eax
+    mov   %eax,retval
+  end;
+  Sys_Lseek:=checkreturnvalue(retval,retval);
+end;
+
+Function Sys_Read(f:longint;buffer:pchar;count:longint):longint;
+
+var retval: LONGINT;
+
+begin
+  asm
+    pushl Count
+    pushl Buffer
+    pushl F
+    mov   $3,%eax
+    int   $0x80
+    addl  $12,%eax
+    mov   %eax,retval
+  end;   
+  Sys_Read:=checkreturnvalue(retval,retval);
+
+end;
+
+Function Sys_Write(f:longint;buffer:pchar;count:longint):longint;
+
+var retval: LONGINT;
+
+begin
+  asm
+    pushl Count
+    pushl Buffer
+    pushl F
+    mov   $4,%eax
+    int   $0x80
+    addl  $12,%eax
+    mov   %eax,retval
+  end;   
+ Sys_Write:=checkreturnvalue(retval,retval);
+end;
+
+Function Sys_Unlink(Filename:pchar):longint;
+
+var retval: LONGINT;
+
+begin
+  asm
+    pushl FileName
+    mov   $10,%eax
+    int   $0x80
+    addl  $4,%eax
+    mov   %eax,retval
+  end;   
+ Sys_UnLink:=checkreturnvalue(retval,retval);
+end;
+
+Function Sys_Rename(Oldname,Newname:pchar):longint;
+
+var retval: LONGINT;
+
+begin
+  asm
+    pushl NewName
+    pushl OldName
+    mov   $38,%eax
+    int   $0x80
+    addl  $8,%eax
+    mov   %eax,retval
+  end;   
+ Sys_Rename:=checkreturnvalue(retval,retval);
+end;
+
+Function Sys_Stat(Filename:pchar;var Buffer: stat):longint;
+{
+   We need this for getcwd
+}
+var
+  regs : SysCallregs;
+begin
+  regs.reg2:=longint(filename);
+  regs.reg3:=longint(@buffer);
+  Sys_Stat:=SysCall(SysCall_nr_stat,regs);
+end;
+
+
+Function Sys_Symlink(oldname,newname:pchar):longint;
+{
+  We need this for erase
+}
+var
+  regs : SysCallregs;
+begin
+  regs.reg2:=longint(oldname);
+  regs.reg3:=longint(newname);
+  Sys_symlink:=SysCall(SysCall_nr_symlink,regs);
+end;
+
+
+{*****************************************************************************
+               --- Directory:Directory related calls ---
+*****************************************************************************}
+
+
+Function Sys_Chdir(Filename:pchar):longint;
+var
+  regs : SysCallregs;
+
+begin
+  regs.reg2:=longint(filename);
+  Sys_ChDir:=SysCall(SysCall_nr_chdir,regs);
+end;
+
+
+
+Function Sys_Mkdir(Filename:pchar;mode:longint):longint;
+var
+  regs : SysCallregs;
+begin
+  regs.reg2:=longint(filename);
+  regs.reg3:=mode;
+  Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs);
+end;
+
+
+
+Function Sys_Rmdir(Filename:pchar):longint;
+var
+  regs : SysCallregs;
+begin
+  regs.reg2:=longint(filename);
+  Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs);
+end;
+
+
+
+{ we need this for getcwd }
+Function OpenDir(f:pchar):pdir;
+var
+  fd:integer;
+  st:stat;
+  ptr:pdir;
+begin
+  opendir:=nil;
+  if sys_stat(f,st)<0 then
+   exit;
+{ Is it a dir ? }
+  if not((st.mode and $f000)=$4000)then 
+   begin
+     errno:=sys_enotdir;
+     exit
+   end;
+{ Open it}
+  fd:=sys_open(f,OPEN_RDONLY,438);
+  if fd<0 then
+   exit;
+  new(ptr);
+  if ptr=nil then
+   exit;
+  new(ptr^.buf);
+  if ptr^.buf=nil then
+   exit;
+  ptr^.fd:=fd;
+  ptr^.loc:=0;
+  ptr^.size:=0;
+  ptr^.dd_max:=sizeof(ptr^.buf^);
+  opendir:=ptr;
+end;
+
+
+
+function CloseDir(p:pdir):integer;
+begin
+  closedir:=sys_close(p^.fd);
+  dispose(p^.buf);
+  dispose(p);
+end;
+
+
+
+Function Sys_ReadDir(p:pdir):pdirent;
+var
+  regs :SysCallregs;
+  dummy:longint;
+begin
+  regs.reg3:=longint(p^.buf);
+  regs.reg2:=p^.fd;
+  regs.reg4:=1;
+  dummy:=SysCall(SysCall_nr_readdir,regs);
+{ the readdir system call returns the number of bytes written }
+  if dummy=0 then 
+   sys_readdir:=nil 
+  else 
+   sys_readdir:=p^.buf
+end;
+
+
+{*****************************************************************************
+        --- Process:Process & program handling - related calls ---
+*****************************************************************************}
+
+Procedure Sys_Exit(ExitCode:Integer);
+var
+  regs : SysCallregs;
+begin
+  regs.reg2:=exitcode;
+  SysCall(SysCall_nr_exit,regs)
+end;
+
+{
+  $Log$
+  Revision 1.1  2000-02-02 15:41:56  marco
+   * Initial BSD version. Still needs a lot of work.
+
+
+}
\ No newline at end of file