////////////////////////////////////////////////////////////////////////////////
// Chip.cpp -- this file is part of the Emulator Developers Kit
// available at http://ourworld.compuserve.com/homepages/pc64/develop.htm

RegisterPersistentClass(Chip);


////////////////////////////////////////////////////////////////////////////////
// set a new clock

global void Chip::SetClock(Clock& NewClock) {

  // store pointer to clock
  if (IsBusy()) {
    SetIdle();
    pClock = &NewClock;
    SetBusy();
  } else {
    pClock = &NewClock;
  }

  // set clock for the parent class
  Object::SetClock(NewClock);
}


////////////////////////////////////////////////////////////////////////////////
// a Chip is linked in after the clock (o2 low phase)
// a CPU is linked in before the clock (o2 high phase)

global void Chip::SetBusy() {

  // check conditions
  assert(!IsBusy());
  assert(pClock != this);
  assert(pfnOnClock != NULL);

  // link into the clock list
  if (pClock != NULL) {
    assert(((Chip*)((Chip*)pClock)->pNextChip)->pPrevChip == pClock);
    assert(((Chip*)((Chip*)pClock)->pPrevChip)->pNextChip == pClock);
    pNextChip = ((Chip*)pClock)->pNextChip;
    ((Chip*)((Chip*)pClock)->pNextChip)->pPrevChip = this;
    pPrevChip = (Chip*)pClock;
    ((Chip*)pClock)->pNextChip = this;
  }

  // set busy flag
  fBusy = true;
}


////////////////////////////////////////////////////////////////////////////////
// link out of clock chain in order to save time

global void Chip::SetIdle() {

  // check conditions
  assert(IsBusy());
  assert(pClock != this);

  // remove object from the clock list
  if (pClock != NULL) {
    assert(pNextChip->pPrevChip == this);
    assert(pPrevChip->pNextChip == this);
    pNextChip->pPrevChip = pPrevChip;
    pPrevChip->pNextChip = pNextChip;
  }

  // set flag
  fBusy = false;
}
