/* CPU Server */!!

inherit(ProvidedLibs, #CpuLib, nil, 2, nil)!!

now(class(CpuLib))!!

/* semiPRIVATE -- should only be called via require(CpuLib)
   Define entry points and load library.  Define any structs required.
*/
Def provide(self, path)
{
  ^initialise( new(self:ancestor), path )
}
!!

now(CpuLib)!!

/* 3/23/1998 19:52 PUBLIC - Created by Eric */
Def setTimer(self, timerID, bool | byte)
{
  if bool /* N.B.: Actor bool: nil=false, else true */
  then byte := 1 ;
  else byte := 0 ;
  endif ;
  
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUSETTIMER], timerID, byte ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;
  if (lastError <> GOOD) then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^byte
}  

!!

/* 3/23/1998 19:49 PUBLIC */
Def getTimer(self, timerID | bool  timerRef)
{
  timerRef := new( Struct, 4 ) ;
  
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETTIMER], timerID, timerRef ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;
  
  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^(atLSB(timerRef, 0) <> 0) /* return nil if byte is 0 */
}
!!

/* PUBLIC */
Def resetCpuOnly(self)
{
  /* 04/25/94 - Nghia
  ** Move the warning message here to be centralized for all caller
  */
  if (errMessageBox(ErrorTextLibClass$Inst, "Warning",
    "Reset target processor without updating window?",
    MB_YESNO bitOr MB_ICONQUESTION, HE_DLGM_CPUPRESE_1) = IDNO) then
    ^nil;
  endif;
  
  if pcallLock(self)
    lastError := pcall(procs[#CPURESETCPUONLY]);
    pcallUNLock(self);
  else
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError <> GOOD)
    displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);
    ^nil;
  endif;
  ^lastError
}!!

/* PUBLIC */
Def getRegisterWidth(self, regId | name sortIndex type width regIndex visibility)
{
  sortIndex := new( Struct, 4 ) ;
  type := new( Struct, 4 ) ;
  width := new( Struct, 4 ) ;
  name := new( Struct, 40) ;
  regIndex := new( Struct, 4) ;
  visibility := new (Struct, 4) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERINFO], regId, name, sortIndex, type, width,
                       regIndex, visibility) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^wordAt(width,0);
}
!!

/* PUBLIC */
Def getRegisterSortIndex(self, regId | name sortIndex type width regIndex visibility)
{
  sortIndex := new( Struct, 4 ) ;
  type := new( Struct, 4 ) ;
  width := new( Struct, 4 ) ;
  name := new( Struct, 40) ;
  regIndex := new( Struct, 4) ;
  visibility := new (Struct, 4) ;

  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERINFO], regId, name, sortIndex, type, width,
                        regIndex, visibility) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^wordAt(sortIndex,0);
}
!!

/* PUBLIC */
Def getRegisterType(self, regId | name sortIndex type width regIndex visibility)
{
  sortIndex := new( Struct, 4 ) ;
  type := new( Struct, 4 ) ;
  width := new( Struct, 4 ) ;
  name := new( Struct, 40) ;
  regIndex := new( Struct, 4) ;
  visibility := new (Struct, 4) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERINFO], regId, name, sortIndex, type, width,
                        regIndex, visibility) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^wordAt(type,0);
}
!!

/* PUBLIC */
Def getRegisterVisibility(self, regId | name sortIndex type width regIndex visibility)
{
  sortIndex := new( Struct, 4 ) ;
  type := new( Struct, 4 ) ;
  width := new( Struct, 4 ) ;
  name := new( Struct, 40) ;
  regIndex := new( Struct, 4) ;
  visibility := new (Struct, 4) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERINFO], regId, name, sortIndex, type, width,
                        regIndex, visibility) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^wordAt(visibility,0);
}
!!

/* PUBLIC */
Def getRegisterName(self, regId | name line sortIndex type width regIndex visibility)
{
  sortIndex := new( Struct, 4 ) ;
  type := new( Struct, 4 ) ;
  width := new( Struct, 4 ) ;
  name := new( Struct, 40) ;
  regIndex := new( Struct, 4) ;
  visibility := new (Struct, 4) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERINFO], regId, name, sortIndex, type, width,
                        regIndex, visibility) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^removeNulls(physicalString(name));
}
!!

/* PUBLIC */
Def getRegisterValueText(self, regId, type | valueText)
{
  valueText := new( Struct, 40) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETREGISTERVALUETEXT], regId, type, valueText ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;   
  ^removeNulls(physicalString(valueText));
}
!!

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

  if (lastError <> GOOD) then
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^wordAt( num, 0 )
}
!!

/* 5/12/1992 13:35 - PUBLIC
  Set stack pointer. 
*/
Def setStackPointer(self, spAddrDesc)
{ 
  /* The CPU server will consume the spAddrDesc */
  if pcallLock(self)
  then
    lastError := pcall(procs[#CPUSETSP], asLong(spAddrDesc));
    pcallUNLock(self);
  else
    lastError := ERR_PCALL_RECURSION ;
  endif ;

  if (lastError <> GOOD)
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;
  ^lastError;  
}
!!

/* 4/1/1992 17:23 - PUBLIC
  Set the Program Counter.
*/
Def setProgramCounter(self, pcAddrDesc)
{ 
  /* The CPU server will consume the pcAddrDesc */
  if pcallLock(self)
  then
    lastError := pcall(procs[#CPUSETPC], asLong(pcAddrDesc));
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;
  ^lastError;  
}
!!

/* PRIVATE */
Def addImportProcs(self)
{
    add(self, #INITCSERVER,             1, #(0, 0));
    add(self, #CPUGETREGISTER,          1, #(0, 1));
    add(self, #CPUSETREGISTER,          1, #(0, 1));
    add(self, #CPUGETFPREGISTER,        1, #(0, 1));
    add(self, #CPUSETFPREGISTER,        1, #(0, 1));
    add(self, #CPUGETPC,                1, #(1));
    add(self, #CPUSETPC,                1, #(1));
    add(self, #CPUGETSP,                1, #(1));
    add(self, #CPUSETSP,                1, #(1));
    add(self, #CPUGETFRAMEPTR,          1, #(1));
    add(self, #CPURESETCPU,             1, nil );
    add(self, #CPURESETCPUONLY,         1, nil );
    add(self, #CPUGETSIGNAL,            1, #(0, 1));
    add(self, #CPUSETSIGNAL,            1, #(0, 0));
    add(self, #CPUGETTIMER,             1, #(0, 1));
    add(self, #CPUSETTIMER,             1, #(0, 0));
    add(self, #CPUFINDREGISTERID,       1, #(1, 1));
    add(self, #CPUGETREGISTERWIDTH,     1, #(0, 1));
    add(self, #CPUGETNUMREGS,           1, #(1));
    add(self, #CPUGETREGISTERINFO,      1, #(0, 1, 1, 1, 1, 1, 1));
    add(self, #CPUGETREGISTERVALUETEXT, 1, #(0, 0, 1));
    add(self, #CPUGETNUMBEROFSIGNALS,   1, #(1));
    add(self, #CPUGETSIGNALNAME,        1, #(0, 1));
    add(self, #CPUCONVTEXTTOVALUE,      1, #(1, 0));
 add(self, #CPUGETFATALFLAG,         1, #(1));
}
!!

/* PUBLIC */
Def findRegisterID(self, regName | idRef)
{
  idRef := new( Struct, 4 ) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUFINDREGISTERID], asciiz(regName), idRef ) ;
    pcallUNLock(self);
  else
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;
  ^wordAt( idRef, 0 );
}
!!

/* PUBLIC */
Def getFPRegValue(self, regID | struct80)
{
  struct80 := new( Struct, 10 ) ; /* 10 bytes is 80 bits */
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETFPREGISTER], regID, struct80 ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;    
  ^struct80
}
!!

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

  if (lastError <> GOOD) then
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^longAt( addrRef, 0 )
}
!!

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


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^longAt( valueRef, 0 )
}
!!

/* PUBLIC */
Def getSignal(self, sigID | bool  sigRef)
{
  sigRef := new( Struct, 4 ) ;
  
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETSIGNAL], sigID, sigRef ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^(atLSB(sigRef, 0) <> 0) /* return nil if byte is 0 */
}
!!

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


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^longAt( addrRef, 0 )
}
!!

/* PRIVATE 
   Open and initialize variable server library & load trigger dll
*/
Def initialise(self, path | retVal)
{
   setName( self, path ) ;
   addImportProcs( self ) ;
   load( self ) ;  /* raises alert if fails: alert(System, self, #libLoad) */
   retVal := getFatalFlag(self);

   if not(retVal) cor (retVal <> 0) ^nil;
   endif;
}
!!

/* PUBLIC */
Def reset(self)
{
  /* 04/25/94 - Nghia
  ** Move the warning message here to be centralized for all caller
  */
  if (errMessageBox(ErrorTextLibClass$Inst, "Warning", 
    "Reset target processor and update all windows?",
    MB_YESNO bitOr MB_ICONQUESTION, HE_DLGM_CPUPRESE_1) = IDNO) then
    ^nil;
  endif;

  if pcallLock(self)
    lastError := pcall( procs[#CPURESETCPU]);
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION;
  endif;

  if (lastError <> GOOD)
    displayError(ErrorTextLibClass$Inst, lastError, CHECK_MODE);
    ^nil;
  endif;  
  ^lastError
}
!!

/* PUBLIC */
Def setFPRegValue(self, regID, struct80)
{
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUSETFPREGISTER], regID, struct80 ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^lastError
}
!!

/* PUBLIC */
Def setRegValue(self, regID, newValue)
{
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUSETREGISTER], regID, asLong(newValue) ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^lastError
}
!!

/* PUBLIC */
Def setSignal(self, sigID, bool | byte)
{
  if bool /* N.B.: Actor bool: nil=false, else true */
  then byte := 1 ;
  else byte := 0 ;
  endif ;
  
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUSETSIGNAL], sigID, byte ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD) then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^byte
}
!!

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


  if (lastError <> GOOD)
  then
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;

  ^wordAt(numSignals, 0);
}
!!

/* PUBLIC */
Def getSignalName(self index | sigName)
{
  sigName := new( Struct, 15 ) ; /* 15 is the max signal name */
                                 /* includes the & needed for */
                                 /* keyboard acceleration. */
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETSIGNALNAME], index, sigName ) ;
    pcallUNLock(self);
  else
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then
    displayError(ErrorTextLibClass$Inst,lastError,FORCE_POPUP);
    ^nil;
  endif;
  ^removeNulls(physicalString(sigName));
}
!!

/* PUBLIC */
/* Added this call to be able to handle 386 register */
/* editing. Change made by Dennis Lamb, May 17, 1994 */
Def convTextToValue(self, regString, regId)
{
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUCONVTEXTTOVALUE], asciiz(regString), regId ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^lastError
}
!!

/* PUBLIC */
/* Added by Dennis Lamb */
/* Added this call to get the cpu fatal flag value. This  */
/* flag is 1 if the cpu.cfg file could not be found, else */
/* it is 0.                                               */
Def getFatalFlag(self | flagVal)
{
  flagVal := new( Struct, 2 ) ;
  if pcallLock(self)
  then
    lastError := pcall( procs[#CPUGETFATALFLAG], flagVal ) ;
    pcallUNLock(self);
  else 
    lastError := ERR_PCALL_RECURSION ;
  endif ;


  if (lastError <> GOOD)
  then 
    displayError(ErrorTextLibClass$Inst,lastError,CHECK_MODE);
    ^nil;
  endif;  
  ^wordAt( flagVal, 0 )
}
!!

