--
--	Inmos Libraries
--	Copyright (C) 1988, 1989, 1990, 1991, 1993  Inmos Limited
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	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
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library; if not, write to the Free Software
--	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
--

--** @module hostsp

--
-- SP Protocol server process
--
-- $Source: /u3/proj/kroc/develop/inmos/libs/hostsp/RCS/spserver.occ,v $
--
-- $Id: spserver.occ,v 1.1 1996/10/03 16:34:24 djb1 Exp $
--
-- (C) Copyright 1996 M.D. Poole <M.D.Poole@ukc.ac.uk>
-- University of Kent at Canterbury
--

--
-- frmb note: we might not actually want this keyboard thing in here anymore..
--

#INCLUDE "hostio.inc"
PROC spserver (CHAN OF BYTE keyboard,
	       CHAN OF SP to.server, from.server, INT32 Status)
  -- Feof, Ferror, Core and DOS special operations are not implemented.

  #INCLUDE "hostunix.occ"
  BOOL going:
  [sp.max.packet.size]BYTE spbuffer:
  INT16 splen:
  BYTE sptag, spres:
  INT32 strid:
  CHAN OF SP dumfs, dumts:
  SEQ
    going := TRUE
    --{{{  main loop
    WHILE going
      SEQ
	to.server ? splen::spbuffer
	sptag := spbuffer[0]
	CASE sptag
	  --{{{  Filing System
	  --{{{  Fopen
	  sp.open.tag
	    INT16 nlen:
	    INT tbi:
	    BOOL ok:
	    SEQ
	      [2]BYTE b.nlen RETYPES nlen:
	      b.nlen := [spbuffer FROM 1 FOR 2]
	      VAL name IS [spbuffer FROM 3 FOR INT nlen]:
	      VAL type IS spbuffer[(INT nlen)+3]:
	      VAL mode IS spbuffer[(INT nlen)+4]:
	      so.open (dumfs, dumts, name, type, mode, strid, spres)
	      spbuffer[0] := spres
	      #PRAGMA DEFINED strid
	      [4]BYTE b.strid RETYPES strid:
	      [spbuffer FROM 1 FOR 4] := b.strid
	      from.server ! INT16 5 :: spbuffer
	  --}}}  
	  --{{{  Fclose
	  sp.close.tag
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      so.close (dumfs, dumts, strid, spres)
	      spbuffer[0] := spres
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Fread
	  sp.read.tag
	    INT16 count:
	    INT bytes.read:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.count RETYPES count:
	      b.count := [spbuffer FROM 5 FOR 2]
	      block IS [spbuffer FROM 3 FOR INT count]:
	      so.read (dumfs, dumts, strid, bytes.read, block)
	      spbuffer[0] := spr.ok
	      VAL [2]BYTE b.blen RETYPES INT16 bytes.read:
	      [spbuffer FROM 1 FOR 2] := b.blen
	      from.server ! INT16 (bytes.read + 3) :: spbuffer
	  --}}}  
	  --{{{  Fgets
	  sp.gets.tag
	    INT16 count:
	    INT bytes.read:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.count RETYPES count:
	      b.count := [spbuffer FROM 5 FOR 2]
	      block IS [spbuffer FROM 3 FOR INT count]:
	      so.gets (dumfs, dumts, strid, bytes.read, block, spres)
	      spbuffer[0] := spres
	      VAL [2]BYTE b.blen RETYPES INT16 bytes.read:
	      [spbuffer FROM 1 FOR 2] := b.blen
	      from.server ! INT16 (bytes.read + 3) :: spbuffer
	  --}}}  
	  --{{{  Fwrite
	  sp.write.tag
	    INT16 blen:
	    INT bytes.written:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.blen RETYPES blen:
	      b.blen := [spbuffer FROM 5 FOR 2]
	      VAL block IS [spbuffer FROM 7 FOR INT blen]:
	      so.write (dumfs, dumts, strid, block, bytes.written)
	      spbuffer[0] := spr.ok
	      VAL [2]BYTE b.writ RETYPES INT16 bytes.written:
	      [spbuffer FROM 1 FOR 2] := b.writ
	      from.server ! INT16 3 :: spbuffer
	  --}}}  
	  --{{{  Fputs
	  sp.puts.tag
	    INT16 blen:
	    INT bytes.written:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.blen RETYPES blen:
	      b.blen := [spbuffer FROM 5 FOR 2]
	      VAL block IS [spbuffer FROM 7 FOR INT blen]:
	      so.write (dumfs, dumts, strid, block, bytes.written)
	      so.write (dumfs, dumts, strid, "*c*n", bytes.written)
	      spbuffer[0] := spr.ok
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Fflush
	  sp.flush.tag
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      so.flush (dumfs, dumts, strid, spres)
	      spbuffer[0] := spres
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Fseek
	  sp.seek.tag
	    INT32 Offset, Origin:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [4]BYTE b.Offset RETYPES Offset:
	      b.Offset := [spbuffer FROM 5 FOR 4]
	      [4]BYTE b.Origin RETYPES Origin:
	      b.Origin := [spbuffer FROM 9 FOR 4]
	      so.seek (dumfs, dumts, strid, Offset, Origin, spres)
	      spbuffer[0] := spres
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Ftell
	  sp.tell.tag
	    INT32 Position:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      so.tell (dumfs, dumts, strid, Position, spres)
	      spbuffer[0] := spres
	      [4]BYTE b.Pos RETYPES Position:
	      [spbuffer FROM 1 FOR 4] := b.Pos
	      from.server ! INT16 5 :: spbuffer
	  --}}}  
	  --{{{  Fremove
	  sp.remove.tag
	    INT16 nlen:
	    SEQ
	      [2]BYTE b.nlen RETYPES nlen:
	      b.nlen := [spbuffer FROM 1 FOR 2]
	      VAL name IS [spbuffer FROM 3 FOR INT nlen]:
	      so.remove (dumfs, dumts, name, spres)
	      spbuffer[0] := spres
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Frename
	  sp.rename.tag
	    INT16 nlen1, nlen2:
	    SEQ
	      [2]BYTE b.nlen1 RETYPES nlen1:
	      b.nlen1 := [spbuffer FROM 1 FOR 2]
	      [2]BYTE b.nlen2 RETYPES nlen2:
	      b.nlen2 := [spbuffer FROM (INT nlen1) + 3 FOR 2]
	      VAL oldname IS [spbuffer FROM 3 FOR (INT nlen1)]:
	      VAL newname IS [spbuffer FROM (INT nlen1) + 5 FOR (INT nlen2)]:
	      so.rename (dumfs, dumts, oldname, newname, spres)
	      spbuffer[0] := spres
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
	  --{{{  Fgetblock
	  sp.getblock.tag
	    INT16 count:
	    INT bytes.read:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.count RETYPES count:
	      b.count := [spbuffer FROM 5 FOR 2]
	      block IS [spbuffer FROM 3 FOR INT count]:
	      so.read (dumfs, dumts, strid, bytes.read, block)
	      spbuffer[0] := spr.ok
	      VAL [2]BYTE b.blen RETYPES INT16 bytes.read:
	      [spbuffer FROM 1 FOR 2] := b.blen
	      from.server ! INT16 (bytes.read + 3) :: spbuffer
	  --}}}  
	  --{{{  Fputblock
	  sp.putblock.tag
	    INT16 blen:
	    INT bytes.written:
	    SEQ
	      [4]BYTE b.strid RETYPES strid:
	      b.strid := [spbuffer FROM 1 FOR 4]
	      [2]BYTE b.blen RETYPES blen:
	      b.blen := [spbuffer FROM 5 FOR 2]
	      VAL block IS [spbuffer FROM 7 FOR INT blen]:
	      so.putblock (dumfs, dumts, strid, block, bytes.written, spres)
	      spbuffer[0] := spres
	      VAL [2]BYTE b.writ RETYPES INT16 bytes.written:
	      [spbuffer FROM 1 FOR 2] := b.writ
	      from.server ! INT16 3 :: spbuffer
	  --}}}  
	  --}}}  
	  --{{{  Host
	  --{{{  Getenv
	  sp.getenv.tag
	    [sp.max.getenvname.size]BYTE envname:
	    INT16 nlen:
	    INT vlen:
	    SEQ
	      [2]BYTE b.nlen RETYPES nlen:
	      b.nlen := [spbuffer FROM 1 FOR 2]
	      envname IS [envname FROM 0 FOR INT nlen]:
	      SEQ
		envname := [spbuffer FROM 3 FOR INT nlen]
		envval IS [spbuffer FROM 3 FOR sp.max.getenvname.size]:
		so.getenv (dumfs, dumts, envname, vlen, envval, spres)
	      spbuffer[0] := spres
	      VAL [2]BYTE b.vlen RETYPES INT16 vlen:
	      [spbuffer FROM 1 FOR 2] := b.vlen
	      from.server ! INT16(vlen+3) :: spbuffer
	  --}}}  
	  --{{{  Time
	  sp.time.tag
	    INT32 LT, UT:
	    SEQ
	      so.time (dumfs, dumts, LT, UT)
	      VAL [4]BYTE b.lt RETYPES LT:
	      [spbuffer FROM 1 FOR 4] := b.lt
	      VAL [4]BYTE b.ut RETYPES UT:
	      [spbuffer FROM 5 FOR 4] := b.ut
	      spbuffer[0] := spr.ok
	      from.server ! INT16 9 :: spbuffer
	  --}}}  
	  --{{{  System
	  sp.system.tag
	    INT32 Status:
	    INT16 clen:
	    SEQ
	      [2]BYTE b.clen RETYPES clen:
	      b.clen := [spbuffer FROM 1 FOR 2]
	      VAL[]BYTE syscomd RETYPES [spbuffer FROM 3 FOR INT clen]:
	      so.system (dumfs, dumts, syscomd, Status, spres)
	      #PRAGMA DEFINED Status
	      VAL [4]BYTE b.Stat RETYPES Status:
	      [spbuffer FROM 1 FOR 4] := b.Stat
	      spbuffer[0] := spres
	      from.server ! INT16 5 :: spbuffer
	  --}}}  
	  --{{{  Exit
	  sp.exit.tag
	    SEQ
	      [4]BYTE b.stat RETYPES Status:
	      b.stat := [spbuffer FROM 1 FOR 4]
	      --so.exit (dumfs, dumts, Status)
	      spbuffer[0] := spr.ok
	      from.server ! INT16 1 :: spbuffer
	      going := FALSE
	  --}}}  
	  --{{{  Commandline
	  sp.commandline.tag
	    INT llen:
	    SEQ
	      VAL all IS spbuffer[1]:
	      []BYTE cline IS [spbuffer FROM 3 FOR sp.max.systemcommand.size]:
	      so.commandline (dumfs, dumts, all, llen, cline, spres)
	      VAL [2]BYTE b.llen RETYPES INT16 llen:
	      [spbuffer FROM 1 FOR 2] := b.llen
	      spbuffer[0] := spres
	      from.server ! INT16(llen + 3) :: spbuffer
	  --}}}  
	  --{{{  Version
	  sp.version.tag
	    SEQ
	      BYTE Version IS spbuffer[1]:
	      BYTE Host IS spbuffer[2]:
	      BYTE OS IS spbuffer[3]:
	      BYTE Board IS spbuffer[4]:
	      so.version (dumfs, dumts, Version, Host, OS, Board)
	      spbuffer[0] := spr.ok
	      from.server ! INT16 5 :: spbuffer
	  --}}}  
	  --}}}  
	  --{{{  COMMENT Keyboard (version not using the keyboard channel)
	  --{{{  Getkey
	  --sp.getkey.tag
	    --SEQ
	      --BYTE key IS spbuffer[1]:
	      --so.getkey (dumfs, dumts, key, spres)
	      --spbuffer[0] := spres
	      --from.server ! INT16 2 :: spbuffer
	  --}}}  
	  --{{{  Pollkey
	  --sp.pollkey.tag
	    --SEQ
	      --BYTE key IS spbuffer[1]:
	      --so.pollkey (dumfs, dumts, key, spres)
	      --spbuffer[0] := spres
	      --from.server ! INT16 2 :: spbuffer
	  --}}}  
	  --}}}  
	  --{{{  Keyboard
	  --{{{  Getkey
	  sp.getkey.tag
	    SEQ
	      BYTE key IS spbuffer[1]:
	      keyboard ? key
	      spbuffer[0] := spr.ok
	      from.server ! INT16 2 :: spbuffer
	  --}}}  
	  --{{{  Pollkey
	  sp.pollkey.tag
	    SEQ
	      BYTE key IS spbuffer[1]:
	      PRI ALT
		keyboard ? key
		  spres := spr.ok
		TRUE & SKIP
		  spres := spr.operation.failed
	      spbuffer[0] := spres
	      from.server ! INT16 2 :: spbuffer
	  --}}}  
	  --}}}  
	  --{{{  Not implemented
	  --{{{  Feof
	  --}}}  
	  --{{{  Ferror
	  --}}}  
	  --{{{  Core
	  --}}}  
	  ELSE
	    SEQ
	      spbuffer[0] := spr.not.implemented
	      from.server ! INT16 1 :: spbuffer
	  --}}}  
    --}}}  
:

