/* ProcLib - PROCLIB.CLS
 */!!

inherit(ProvidedLibs, #ProcLib, #(maxOutputDigit
systemTypeRetrieved
    /* true if system type retrieved */
systemType
    /* system type if systemTypeRetrieved */
cpuTypeRetrieved
    /* true if cpu type retrieved */
cpuType
    /* cpu type if cpuTypeRetrieved */
micepackTested
    /* true if we've tested for micepack */
micepackDetected
   /* true if this is a micepack */), 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)!!

/* 3/4/1997 8:33 */
 
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 ;
}!!

/* 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)
{
  /* avoid calling DLL if it's already been successful */
  if systemTypeRetrieved
    ^systemType;
  endif;

  systemStruct := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#PROCRETURNSYSTEMTYPE], systemStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError = 0)
    /* save system type info if pcall successful */
    systemType := wordAt(systemStruct, 0);
    systemTypeRetrieved := 0;
    ^systemType;
  else
    displayError(ErrorTextLibClass$Inst,lastError, CHECK_MODE);
    ^nil
  endif;
}!!

/* PUBLIC */
Def getCpuType(self | systemStruct)
{
  /* avoid calling DLL if it's already been successful */
  if cpuTypeRetrieved
    ^cpuType;
  endif;

  systemStruct := new(Struct, 4);
  if pcallLock(self)
    lastError := pcall(procs[#PROCRETURNCPU], systemStruct);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError = 0)
    cpuType := wordAt(systemStruct, 0);
    cpuTypeRetrieved := 0;
    ^cpuType;
  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, #INITCSERVER,                     1, #(0, 0));
  add(self, #PROCRETURNTRACEMODULE,           1, #(1) );

}!!
