void __cdecl CgebEmu(unsigned short cs, CGEBFPS *fps, unsigned short ds)
  {
  // fps->status defaults to CGEB_SUCCESS on the first step
  // so if we just return, it indicates success

  switch (fps->fct) {

    case xCgebGetCgebVersion:
      fps->rets[0]=(CGEB_VERSION_MAJOR<<24)|0x000067;
      return;

    case xCgebGetDataSize:
      fps->rets[0]=0;
      return;

    case xCgebGetSysBiosVersion:
      fps->rets[0]=0x01230000;
      return; // success

    case xCgebGetVgaBiosVersion:
    case xCgebOpen:
    case xCgebClose:
    case xCgebMapGetMem:
    case xCgebMapChanged:
//    case xCgebMapGetPorts:
    case xCgebDelayUs:
//    case xCgebGgbcReadWrite:
    case xCgebWDogTrigger:
    case xCgebWDogSetConfig:
      fps->rets[0]=0;
      return; // success

    case xCgebWDogCount:
    case xCgebVgaCount:
    case xCgebI2CCount:
      fps->rets[0]=1; // one unit available
      return;

    case xCgebBoardGetInfo:
      fps->optr=&boardinfo;
      return;

    case xCgebWDogGetInfo:
      if (fps->unit) break; // only one unit
      fps->optr=&wdinfo;
      return;

    case xCgebVgaGetInfo:
      if (fps->unit) break; // only one unit
      fps->optr=&vgainfo;
      return;

    case xCgebI2CGetInfo:
      if (fps->unit) break; // only one unit
      fps->optr=&i2cinfo;
      return;

    case xCgebI2CTransfer: {
      unsigned int i;
      dbpf((TT("EMUL: I2C lwr %d, lrd %d, %s "),fps->pars[0],fps->pars[1],
        fps->pars[2]&CG_I2C_FLAG_START?"START":"     "));
      for (i=0; i<fps->pars[0]; i++)
        dbpf((TT("%02X "),((unsigned char *)fps->iptr)[i]));
      dbpf((TT("%s\n"),
        fps->pars[2]&CG_I2C_FLAG_STOP?"STOP":"    "));
      if (fps->pars[1])
        OsaMemSet(fps->optr,(char)0xaa,fps->pars[1]); // fill read data with 0xaa
      fps->rets[0]=fps->pars[1]; // return read count
      return;
      }

    case xCgebStorageAreaCount:
      fps->rets[0]=NUM_STO;
      return;

    case xCgebStorageAreaGetInfo:
      if (fps->unit>=NUM_STO) break;
      fps->optr=&stoinfos[fps->unit];
      return;

    case xCgebStorageAreaRead:
      if (fps->unit>=NUM_STO) break;
      if (fps->pars[0]+fps->pars[1]>stoinfos[fps->unit].areaSize) {
        fps->status=CGEB_INVALID_PARAMETER;
        return;
        }
      OsaMemCpy(fps->optr,(fps->unit?(char *)&sda:(char *)userbytes)+fps->pars[0],fps->pars[1]);
      fps->rets[0]=fps->pars[1]; // return read count
      return;

    case xCgebStorageAreaWrite:
      if (fps->unit>=1) break; // allow writes only to user bytes
      if (fps->pars[0]+fps->pars[1]>stoinfos[fps->unit].areaSize) {
        fps->status=CGEB_INVALID_PARAMETER;
        return;
        }
      OsaMemCpy((fps->unit?(char *)&sda:(char *)userbytes)+fps->pars[0],fps->iptr,fps->pars[1]);
      fps->rets[0]=fps->pars[1]; // return read count
      return;


    case xCgebIOCount:
      fps->rets[0]=NUM_IO;
      return;

    case xCgebIOGetInfo:
      if (fps->unit>=NUM_IO) break;
      fps->optr=&ioinfos[fps->unit];
      return;

    case xCgebIORead:
      if (fps->unit>=NUM_IO) break;
      fps->rets[0]=iovals[fps->unit]; // return read value
      return;

    case xCgebIOWrite:
      if (fps->unit>=NUM_IO) break;
      iovals[fps->unit]=fps->pars[0];
      return;

    case xCgebIOSetDirection:
      if (fps->unit>=NUM_IO) break;
      return;

    case xCgebIOGetDirection:
      if (fps->unit>=NUM_IO) break;
      fps->rets[0]=0xff;
      return;

    }
  // a break returns an error
  fps->status=CGEB_NOT_FOUND;
  }
static void dbpfCallFunc(const iocshArgBuf *args)
{ dbpf(args[0].sval,args[1].sval);}