/* ProcLib - PROCLIB.CLS
 */!!

inherit(ProvidedLibs, #ProcLib, #(maxOutputDigit
micepackTested
   /* true if we've tested for micepack */
micepackDetected
   /* true if this is a micepack */
byteOrder byteOrderFound
   /* little or big endian; see proc.h */), 2, nil)!!

now(class(ProcLib))!!

/* semiPRIVATE -- should only be called via require(MapLib)
   Define entry points and load library.  Define any structs required.
   NOTES: 
      - TheProcFamily is the global processor family identifier.
        It value can be either 
            PROC_FAMILY_UNKNOWN,
            PROC_FAMILY_680X0,
            PROC_FAMILY_X86.
*/
Def provide(self, path | lib)
{
  if (lib := initialise( new(self:ancestor), path)) then
     if not(TheProcFamily := getProcessorFamily(lib)) then
        TheProcFamily := PROC_FAMILY_UNKNOWN;
     endif;
  endif;
  ^lib;
}!!

now(ProcLib)!!

/* PUBLIC */
Def getTraceModule(self | procStruct)
{
  procStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNTRACEMODULE], procStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    if (wordAt(procStruct, 0) = 0)
    then 
      ^nil;
    else
      ^1;
    endif ;
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}
!!
/* PUBLIC */
Def getFetchBoundary(self | boundary)
{ 
  boundary := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNFETCHBOUNDARY], boundary);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(boundary, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

/* 06/16/94 - PUBLIC   Return the byte ordering. */
Def getByteOrder(self | orderingStruct)
{
  /* return value if test already done */
  if byteOrderFound
    ^byteOrder;
  endif;
  
  orderingStruct := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#PROCRETURNBYTEORDERING], orderingStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError = 0)
    byteOrder := wordAt(orderingStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);
    ^nil
  endif;
  
  ^byteOrder;
}!!

/* Get processor name and system type if not already done.
   Return true if micepack.  */
Def micepack?(self)
{
  /* return value if test for processor already done */
  if micepackTested
    ^micepackDetected;
  endif;
  
  /* perform test if not yet done; this should only be done once */
  micepackTested := 0;
  if (getSystemType(self) = PROC_MICEPACK)
    micepackDetected := 0;
  endif;

  ^micepackDetected;
}
!!

/* PUBLIC */
/* 2/11/1993 16:05 */
Def isValidProcessor(self)
{ 
  if (getSpecificProcessor(ProcLibClass$Inst) <> nil)
     then ^1;    /* processor is a valid type */
  endif;
  ^nil;
}
!!

/* PUBLIC */
Def getSystemType(self | systemStruct)
{
  systemStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNSYSTEMTYPE], systemStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(systemStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

/* PUBLIC */
Def getCpuType(self | systemStruct)
{
  systemStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNCPU], systemStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(systemStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

/* PUBLIC */
Def getSpecificProcessor(self | procStruct)
{
  procStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNSPECIFICPROCESSOR], procStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(procStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

/* 03/15/94 - PUBLIC 
  NOTES:
     Instead of calling this method to check for the current processor
     family, use the global 'TheProcFamily' variable.
*/
Def getProcessorFamily(self | familyStruct)
{
  familyStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNPROCFAMILY], familyStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(familyStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

/* PUBLIC */
Def getDemo(self | systemStruct)
{
  systemStruct := new(Struct, 4);
  if pcallLock(self)
  then
    lastError := pcall(procs[#PROCRETURNDEMONSTRATIONVERSION], systemStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif ;

  if (lastError = 0)
  then
    ^wordAt(systemStruct, 0);
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif ;
}!!

Def addImportProcs(self)
{
  add(self, #PROCRETURNBYTEORDER,             1, #(1) );
  add(self, #PROCRETURNBYTESPERINSTR,         1, #(1) );
  add(self, #PROCRETURNFETCHBOUNDARY,         1, #(1) );
  add(self, #PROCRETURNPROCFAMILY,            1, #(1) );
  add(self, #PROCRETURNSPECIFICPROCESSOR,     1, #(1) );
  add(self, #PROCRETURNPROCESSORNAME,         1, #(1) );
  add(self, #PROCRETURNSYSTEMTYPE,            1, #(1) );
  add(self, #PROCRETURNCPU,                   1, #(1) );
  add(self, #PROCRETURNDEMONSTRATIONVERSION,  1, #(1) );
  add(self, #PROCRETURNTRACEMODULE,           1, #(1) );
  add(self, #INITCSERVER,                     1, #(0, 0));

}!!
