
#
# This script generates the 'simple' system calls.

# Each call is put into it's own object file, if the semantics of the
# call are not correct UNIX then the 4th field in the dat file has a
# marker and the function is generated with a __ prefix.
#

# Different levels of squeeze
#   0 = each is complete
#   1 = Short codes
#   2 = At the expense of speed.

COMPACT=1

tr '[A-Z]' '[a-z]' < syscall.dat | \
awk -v COMPACT=$COMPACT 'BEGIN{
   print "# This file is automatically generated\n" > "syscall.mak"
   print "/* This file is automatically generated */\n\n"
   obj="OBJ=__syscall.o ";

   print "/* Standard start */\n\n"
   printf("#asm\n");
   printf("  .text\n");
   printf("  .even\n");
   printf("#endasm\n\n");

   print "/* Shared system call code */\n"
   printf("#ifdef L___syscall\n", funcname);
   printf("#asm\n");
   printf("export syscall_err\n");
   printf("syscall_err:\n");
   printf("  neg   ax\n");
   printf("  mov   [_errno],ax\n");
   printf("  mov   ax,#-1\n");
   printf("  ret\n");
   if( COMPACT )
   {
      if( COMPACT == 2 ) printf("export sys_callX\nsys_callX:\n");
      if( COMPACT == 1 ) printf("export sys_call3\nsys_call3:\n");
      printf("  mov   bx,sp\n");
      printf("  mov   dx,[bx+6]\n");
      if( COMPACT == 1 ) printf("export sys_call2\nsys_call2:\n");
      printf("  mov   cx,[bx+4]\n");
      if( COMPACT == 1 ) printf("export sys_call1\nsys_call1:\n");
      printf("  mov   bx,[bx+2]\n");
      printf("export sys_call0\nsys_call0:\n");

      printf("  int   $80\n");
      printf("  test  ax,ax\n");
      printf("  jl   syscall_err\n");
      printf("  ret\n");
   }
   printf("#endasm\n");
   printf("#endif\n\n");
}
/^[	 ]*#/ { next; }
/^[	 ]*$/ { next; }
{
   if( $3 == "x" || $3 == "" ) next;
   if( $4 == "" || $4 == "." ) funcname=$1;
   else                        funcname="__" $1;

   if( length(obj) > 60 )
   {
      printf("%s\t\\\n", obj) > "syscall.mak";
      obj="    ";
   }
   obj=obj funcname ".o ";

   printf "/* CALL %s */\n\n", $0;

   printf("#ifdef L_%s\n", funcname);
   printf("#asm\n", funcname);
   printf("export _%s\n", funcname);
   printf("_%s:\n", funcname);

   printf("  mov   ax,#%d\n", $2);

   if( COMPACT == 2 )
   {
      if( $3 == 0 )
	 printf("  br    sys_call0\n");
      else
	 printf("  br    sys_callX\n");
   }
   else if( COMPACT == 1 )
   {
      if( $3 == 1 || $3 == 2 )
         printf("  mov   bx,sp\n");

	 printf("  br    sys_call%d\n", $3);
   }
   else
   {
      if( $3 >= 1 )
         printf("  mov   bx,sp\n");
      if( $3 >= 3 )
         printf("  mov   dx,[bx+6]\n");
      if( $3 >= 2 )
         printf("  mov   cx,[bx+4]\n");
      if( $3 >= 1 )
         printf("  mov   bx,[bx+2]\n");

         printf("  int   $80\n");
	 printf("  test  ax,ax\n");
	 printf("  jl   xx\n");
	 printf("  ret\n");
         printf("#endasm\n");
   }
   if( COMPACT == 0 )
   {
         printf("#asm\n");
	 printf("xx:\n  br    syscall_err\n");
   }
   printf("#endasm\n");
   printf("#endif\n\n");
}
END{
   printf("%s\n", obj) > "syscall.mak";
   printf "\n" > "syscall.mak";

}'  > syscall.c

cat >> syscall.mak <<\!
CC=bcc
CFLAGS=-O -0 -I../include

all: $(OBJ)

libc.a: $(OBJ)
	ar r ../libc.a $(OBJ)
	@touch libc.a

clean:
	rm -f $(OBJ) libc.a

$(OBJ): syscall.dat mksyscall
	$(CC) $(CFLAGS) -c -DL_$* -o $@ syscall.c
!

rv=$?
if [ "$rv" != 0 ]
then exit $rv
fi

export MAKELEVEL
MAKELEVEL=0
exec make -f syscall.mak $1 
