Пример #1
0
static VOID WINAPI DosSystemBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        case 0x11:  // Load the DOS kernel
        {
            BOOLEAN Success = FALSE;
            HANDLE  hDosKernel;
            ULONG   ulDosKernelSize = 0;

            DPRINT1("You are loading Windows NT DOS!\n");

            /* Open the DOS kernel file */
            hDosKernel = FileOpen("ntdos.sys", &ulDosKernelSize);

            /* If we failed, bail out */
            if (hDosKernel == NULL) goto Quit;

            /*
             * Attempt to load the DOS kernel into memory.
             * The segment where to load the DOS kernel is defined
             * by the DOS BIOS and is found in DI:0000 .
             */
            Success = FileLoadByHandle(hDosKernel,
                                       REAL_TO_PHYS(TO_LINEAR(getDI(), 0x0000)),
                                       ulDosKernelSize,
                                       &ulDosKernelSize);

            DPRINT1("Windows NT DOS loading %s at 0x%04X:0x%04X, size 0x%x ; GetLastError() = %u\n",
                    (Success ? "succeeded" : "failed"),
                    getDI(), 0x0000,
                    ulDosKernelSize,
                    GetLastError());

            /* Close the DOS kernel file */
            FileClose(hDosKernel);

Quit:
            if (!Success)
            {
                /* We failed everything, stop the VDM */
                EmulatorTerminate();
            }

            break;
        }

        default:
        {

            DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
            // setCF(1); // Disable, otherwise we enter an infinite loop
            break;
        }
    }
}
Пример #2
0
void oClub::set(const xmlobject &xo)
{
  xmlList xl;
  xo.getObjects(xl);

  xmlList::const_iterator it;

  for(it=xl.begin(); it != xl.end(); ++it){
    if (it->is("Id")){
      Id=it->getInt();
    }
    else if (it->is("Name")){
      internalSetName(it->get());
    }
    else if (it->is("oData")){
      getDI().set(*it);
    }
    else if (it->is("Updated")){
      Modified.setStamp(it->get());
    }
    else if (it->is("AltName")) {
      altNames.push_back(it->get());
    }
  }
}
Пример #3
0
void oCourse::setMaximumRogainingTime(int p)
{
  cachedHasRogaining = 0;
  if (p == NOTIME)
    p = 0;
  getDI().setInt("RTimeLimit", p);
}
Пример #4
0
void oCourse::Set(const xmlobject *xo)
{
  xmlList xl;
  xo->getObjects(xl);

  xmlList::const_iterator it;

  for(it=xl.begin(); it != xl.end(); ++it){
    if (it->is("Id")){
      Id=it->getInt();
    }
    else if (it->is("Length")){
      Length=it->getInt();
    }
    else if (it->is("Name")){
      Name=it->get();
    }
    else if (it->is("Controls")){
      importControls(it->get());
    }
    else if (it->is("Legs")) {
      importLegLengths(it->get());
    }
    else if (it->is("oData")){
      getDI().set(*it);
    }
    else if (it->is("Updated")){
      Modified.setStamp(it->get());
    }
  }
}
Пример #5
0
oClub::oClub(oEvent *poe, int id): oBase(poe)
{
  getDI().initData();
  Id=id;
  if (id != cVacantId)
    oe->qFreeClubId = max(id, oe->qFreeClubId);
}
Пример #6
0
// Pass 2 of multiplyByMInv.
// Base to tip: temp allA_GB does not need to be initialized before
// beginning the iteration.
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void 
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::multiplyByMInvPass2Outward(
    const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    const Real*                             allEpsilon,
    SpatialVec*                             allA_GB,
    Real*                                   allUDot) const
{
    const Vec<dof>& eps  = fromU(allEpsilon);
    SpatialVec&     A_GB = allA_GB[nodeNum];
    Vec<dof>&       udot = toU(allUDot); // pull out this node's udot

    const bool isPrescribed = isUDotKnown(ic);
    const HType&        H   = getH(pc);
    const PhiMatrix&    phi = getPhi(pc);
    const Mat<dof,dof>& DI  = getDI(abc);
    const HType&        G   = getG(abc);

    // Shift parent's acceleration outward (Ground==0). 12 flops
    const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()]; 
    const SpatialVec  APlus = ~phi * A_GP;

    // For a prescribed mobilizer, set udot==0.
    if (isPrescribed) {
        udot = 0;
        A_GB = APlus;
    } else {
        udot = DI*eps - ~G*APlus;   // 2dof^2 + 11 dof flops
        A_GB = APlus + H*udot;      // 12 dof flops
    }
}
Пример #7
0
oCourse::oCourse(oEvent *poe) : oBase(poe)
{
  getDI().initData();
  nControls=0;
  Length=0;
  clearCache();
  Id=oe->getFreeCourseId();
}
Пример #8
0
static VOID DemLoadNTDOSKernel(VOID)
{
    BOOLEAN Success = FALSE;
    LPCSTR  DosKernelFileName = "ntdos.sys";
    HANDLE  hDosKernel;
    ULONG   ulDosKernelSize = 0;

    DPRINT1("You are loading Windows NT DOS!\n");

    /* Open the DOS kernel file */
    hDosKernel = FileOpen(DosKernelFileName, &ulDosKernelSize);
    if (hDosKernel == NULL) goto Quit;

    /*
     * Attempt to load the DOS kernel into memory.
     * The segment where to load the DOS kernel is defined
     * by the DOS BIOS and is found in DI:0000 .
     */
    Success = FileLoadByHandle(hDosKernel,
                               REAL_TO_PHYS(TO_LINEAR(getDI(), 0x0000)),
                               ulDosKernelSize,
                               &ulDosKernelSize);

    DPRINT1("Windows NT DOS file '%s' loading %s at %04X:%04X, size 0x%X (Error: %u).\n",
            DosKernelFileName,
            (Success ? "succeeded" : "failed"),
            getDI(), 0x0000,
            ulDosKernelSize,
            GetLastError());

    /* Close the DOS kernel file */
    FileClose(hDosKernel);

Quit:
    if (!Success)
    {
        /* We failed everything, stop the VDM */
        BiosDisplayMessage("Windows NT DOS kernel file '%s' loading failed (Error: %u). The VDM will shut down.\n",
                           DosKernelFileName, GetLastError());
        EmulatorTerminate();
        return;
    }
}
Пример #9
0
BOOL DemDispatch (ULONG iSvc)
{
#if DBG
    if(iSvc < SVC_DEMLASTSVC && (fShowSVCMsg & DEMSVCTRACE) &&
	 apfnSVC[iSvc] != demNotYetImplemented){
	sprintf(demDebugBuffer,"DemDispatch: Entering %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
	       aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI());
        OutputDebugStringOem(demDebugBuffer);
	sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x\n",
                getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP());
        OutputDebugStringOem(demDebugBuffer);
    }
#endif

    if (iSvc >= SVC_DEMLASTSVC){
#if DBG
	sprintf(demDebugBuffer,"Unimplemented SVC index %x\n",iSvc);
        OutputDebugStringOem(demDebugBuffer);
#endif
	setCF(1);
	return FALSE;
    }

    if (pHardErrPacket) {
	pHardErrPacket->vhe_fbInt24 = 0;
    }
    CurrentISVC = iSvc;
    (apfnSVC [iSvc])();


#if DBG
    if((fShowSVCMsg & DEMSVCTRACE)){
	sprintf(demDebugBuffer,"DemDispatch:On Leaving %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
               aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI());
        OutputDebugStringOem(demDebugBuffer);
	sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x CF=%x\n",
                getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP(),getCF());
        OutputDebugStringOem(demDebugBuffer);
    }
#endif
    return TRUE;
}
Пример #10
0
oCourse::oCourse(oEvent *poe, int id) : oBase(poe)
{
  getDI().initData();
  nControls=0;
  Length=0;
  clearCache();
  if (id == 0)
    id = oe->getFreeCourseId();
  Id=id;
  oe->qFreeCourseId = max(id, oe->qFreeCourseId);
}
Пример #11
0
void oCourse::setCommonControl(int ctrlId) {
  if (ctrlId != 0) {
    int found = 0;
    for (int k = 0; k < nControls; k++) {
      if (Controls[k]->getId() == ctrlId)
        found++;
    }
    if (found == 0)
      throw meosException("Kontroll X finns inte på banan#" + itos(ctrlId));
  }
  getDI().setInt("CControl", ctrlId);
}
Пример #12
0
void oCourse::setStart(const string &start, bool sync)
{
  if (getDI().setString("StartName", start)) {
    if (sync)
      synchronize();
    oClassList::iterator it;
    for (it=oe->Classes.begin();it!=oe->Classes.end();++it) {
      if (it->getCourse()==this) {
        it->setStart(start);
        if (sync)
          it->synchronize();
      }
    }
  }
}
Пример #13
0
void GEN_CSV_WRITER::writeCSVFileLine(){
  if(0 != m_pstCSVFile){
    char acBuffer[100];
    for(int i = 2; i < m_pstInterfaceSpec->m_nNumDIs; i++){
      int nLen = getDI(i)->toString(acBuffer, 100);
      fwrite(acBuffer, 1, nLen, m_pstCSVFile);
      fwrite("; ", 1, 2, m_pstCSVFile);
    }
    fwrite("\n", 1, 1, m_pstCSVFile);
  }
  else{
    QO() = false;
    STATUS() = "File not opened";
  }
}
Пример #14
0
bool oClub::write(xmlparser &xml)
{
  if (Removed) return true;

  xml.startTag("Club");
  xml.write("Id", Id);
  xml.write("Updated", Modified.getStamp());
  xml.write("Name", name);
  for (size_t k=0;k<altNames.size(); k++)
    xml.write("AltName", altNames[k]);

  getDI().write(xml);

  xml.endTag();

  return true;
}
Пример #15
0
void FORTE_X20DO4623::executeEvent(int pa_nEIID){
  switch(pa_nEIID){
    case scm_nEventINITID:
      if(QI() == true){
        m_bInitOk = false;

        CEplStackWrapper &eplStack = CEplStackWrapper::getInstance();

        // Get settings for intputs
        CProcessImageMatrix* moduleIOs = eplStack.getProcessImageMatrixIn()->getModuleEntries(CNID(), MODID());

        if(moduleIOs){
          // Outputs (process inputs) always start with i = 0
          // Check xap.xml if a BitUnused is present
          for(unsigned int i = 0; i < moduleIOs->getNrOfEntries() - 1; i++){
            m_oEplMapping.m_lCurrentValues.push_back(new SEplMapping::SEplMappingValues(moduleIOs->getEntry(i)[0], moduleIOs->getEntry(i)[1], moduleIOs->getEntry(i)[2]));
          }

          delete moduleIOs;

          eplStack.registerCallback((IEplCNCallback*) this);

          m_bInitOk = true;
        }
      }
      QO() = QI();
      CNIDO() = CNID();
      sendOutputEvent(scm_nEventINITOID);
      break;
    case scm_nEventREQID:
      if(QI() == true && m_bInitOk){
        m_oSync.lock();
        SEplMapping::TEplMappingList::Iterator itEnd = m_oEplMapping.m_lCurrentValues.end();
        SEplMapping::TEplMappingList::Iterator it = m_oEplMapping.m_lCurrentValues.begin();
        for(int i = 3; i < m_pstInterfaceSpec->m_nNumDIs && it != itEnd; i++, ++it){
          bool ioVal = *static_cast<CIEC_BOOL*>(getDI(i));
          *(it->m_pchCurrentValue) = (char) ioVal;
        }
        m_oSync.unlock();
      }
      QO() = QI();
      sendOutputEvent(scm_nEventCNFID);
      break;
  }
}
Пример #16
0
bool oCourse::Write(xmlparser &xml)
{
  if (Removed) return true;

  xml.startTag("Course");

  xml.write("Id", Id);
  xml.write("Updated", Modified.getStamp());
  xml.write("Name", Name);
  xml.write("Length", Length);
  xml.write("Controls", getControls());
  xml.write("Legs", getLegLengths());

  getDI().write(xml);
  xml.endTag();

  return true;
}
Пример #17
0
//
// Calculate acceleration in internal coordinates, based on the last set
// of forces that were reduced into epsilon (e.g., see above).
// Base to tip: temp allA_GB does not need to be initialized before
// beginning the iteration.
//
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void 
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::calcUDotPass2Outward(
    const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    const SBTreeVelocityCache&              vc,
    const SBDynamicsCache&                  dc,
    const Real*                             allEpsilon,
    SpatialVec*                             allA_GB,
    Real*                                   allUDot,
    Real*                                   allTau) const
{
    const Vec<dof>& eps  = fromU(allEpsilon);
    SpatialVec&     A_GB = allA_GB[nodeNum];
    Vec<dof>&       udot = toU(allUDot);    // pull out this node's udot

    const bool isPrescribed = isUDotKnown(ic);
    const HType&              H   = getH(pc);
    const PhiMatrix&          phi = getPhi(pc);
    const ArticulatedInertia& P   = getP(abc);
    const SpatialVec&         a   = getMobilizerCoriolisAcceleration(vc);
    const Mat<dof,dof>&       DI  = getDI(abc);
    const HType&              G   = getG(abc);

    // Shift parent's acceleration outward (Ground==0). 12 flops
    const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()]; 
    const SpatialVec  APlus = ~phi * A_GP;

    if (isPrescribed) {
        Vec<dof>& tau = updTau(ic,allTau);  // pull out this node's tau
        // This is f - ~H(P*APlus + z); compare Jain 16.17b. Note sign
        // change since our tau is on the LHS while his is on the RHS.
        tau = eps - ~H*(P*APlus); // 66 + 12*dof flops
    } else {
        udot = DI*eps - ~G*APlus; // 2*dof^2 + 11*dof
    }

    A_GB = APlus + H*udot + a;
}
Пример #18
0
void MS_bop_F(void)
{
    extern void kb_setup_vectors(void);


    kb_setup_vectors();


#ifdef MONITOR

    AddrIretBopTable = ( ((ULONG)getDS() << 16) | (ULONG)getDI() );

#ifndef PROD
    if (getCX() != VDM_RM_IRETBOPSIZE) {
        OutputDebugString("NTVDM:spacing != VDM_RM_IRETBOPSIZE\n");
        DebugBreak();
        }
#endif
#endif

    /*
     * Now that spckbd is loaded, and the ivt rom vectors are hooked
     * we can allow hw interrupts.
     */
    // nt_init_event_thread will resume the event thread after it
    // sync up BIOS led states with the system
    // ResumeThread(ThreadInfo.EventMgr.Handle);
    host_ica_lock();
    DelayIrqLine = 0;
    if (!ica_restart_interrupts(ICA_SLAVE))
        ica_restart_interrupts(ICA_MASTER);
    host_ica_unlock();

#ifdef MONITOR
    setCF(1);
#else
    setCF(0);
#endif
}
Пример #19
0
VOID demLockOper (VOID)
{
HANDLE	hFile;
DWORD	dwFileOffset,cbLock;

    // Collect all the parameters
    hFile = GETHANDLE(getBX(),getBP());
    dwFileOffset = GETULONG (getCX(),getDX());
    cbLock = GETULONG (getSI(),getDI());

    if(getAL() == 0){  // Locking case
	if (LockFile (hFile,
		      dwFileOffset,
		      0,
		      cbLock,
		      0
		     ) == TRUE) {
	    setCF (0);
	    return;
	}
    }
    else {
	if (UnlockFile (hFile,
			dwFileOffset,
			0,
			cbLock,
			0
		       ) == TRUE) {
	    setCF (0);
	    return;
	}
    }

    // Operation failed
    demClientError(hFile, (CHAR)-1);
    return;
}
Пример #20
0
//==============================================================================
//                                  REALIZE Y
//==============================================================================
// To be called base to tip.
// This is calculating what Abhi Jain calls the operational space compliance
// kernel in his 2011 book. This is the inverse of the operational space inertia
// for each body at its body frame. Also, see Equation 20 in Rodriguez,Jain, 
// & Kreutz-Delgado:  A spatial operator algebra 
// for manipulator modeling and control. Intl. J. Robotics Research 
// 10(4):371-381 (1991).
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::realizeYOutward
   (const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    SBDynamicsCache&                        dc) const
{
    if (isUDotKnown(ic)) {
        //TODO: (sherm 090810) is this right?
        assert(false);
        //updY(dc) = (~getPhi(pc) * parent->getY(dc)) * getPhi(pc); // rigid shift
        return;
    }

    // Compute psi. Jain has TauBar=I-G*~H but we're negating that to G*~H-I 
    // because we can save 30 flops by just subtracting 1 from the diagonals 
    // rather than having to negate all the off-diagonals. Then Psi ends up 
    // with the wrong sign here also, which doesn't matter because we multiply 
    // by it twice.

    SpatialMat tauBar = getG(abc)*~getH(pc);// 11*dof^2 flops
    tauBar(0,0) -= 1; // subtract identity matrix (only touches diags: 3 flops)
    tauBar(1,1) -= 1; //    "    (3 flops)
    SpatialMat psi = getPhi(pc)*tauBar; // ~100 flops

    // TODO: this is very expensive (~1000 flops?) Could cut be at least half
    // by exploiting symmetry. Also, does Psi have special structure?
    // And does this need to be computed for every body or only those
    // which are loop "base" bodies or some such?


    // Psi here has the opposite sign from Jain's, but we're multiplying twice
    // by it here so it doesn't matter.
    updY(dc) = (getH(pc) * getDI(abc) * ~getH(pc)) 
                + (~psi * parent->getY(dc) * psi);
}
Пример #21
0
void oCourse::setNumberMaps(int block)
{
  getDI().setInt("NumberMaps", block);
}
Пример #22
0
__declspec(dllexport) void __cdecl VDDDispatch(void) 
{
	char			str[512];
	DWORD			count;
	DWORD			msgs;
	int				retval;
	int				node_num;
	BYTE*			p;
	vdd_status_t*	status;
	static  DWORD	writes;
	static  DWORD	bytes_written;
	static	DWORD	reads;
	static  DWORD	bytes_read;
	static  DWORD	inbuf_poll;
	static	DWORD	online_poll;
	static	DWORD	status_poll;
	static	DWORD	vdd_yields;
	static	DWORD	vdd_calls;
	VDD_IO_HANDLERS  IOHandlers = { NULL };
	static VDD_IO_PORTRANGE PortRange;

	retval=0;
	node_num=getBH();

	lprintf(LOG_DEBUG,"VDD_OP: (handle=%d) %d (arg=%X)", getAX(),getBL(),getCX());
	vdd_calls++;

	switch(getBL()) {

		case VDD_OPEN:

			sscanf("$Revision: 1.40 $", "%*s %s", revision);

			lprintf(LOG_INFO,"Synchronet Virtual Device Driver, rev %s %s %s"
				,revision, __DATE__, __TIME__);
#if 0
			sprintf(str,"sbbsexec%d.log",node_num);
			fp=fopen(str,"wb");
#endif

			sprintf(str,"\\\\.\\mailslot\\sbbsexec\\wr%d",node_num);
			rdslot=CreateMailslot(str
				,0 //LINEAR_RX_BUFLEN		/* Max message size (0=any) */
				,MAILSLOT_WAIT_FOREVER 	/* Read timeout */
				,NULL);
			if(rdslot==INVALID_HANDLE_VALUE) {
				lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s"
					,GetLastError(),str);
				retval=1;
				break;
			}

			sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d",node_num);
			wrslot=CreateFile(str
				,GENERIC_WRITE
				,FILE_SHARE_READ
				,NULL
				,OPEN_EXISTING
				,FILE_ATTRIBUTE_NORMAL
				,(HANDLE) NULL);
			if(wrslot==INVALID_HANDLE_VALUE) {
				lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s"
					,GetLastError(),str);
				retval=2;
				break;
			}

			if(RingBufInit(&rdbuf, RINGBUF_SIZE_IN)!=0) {
				retval=3;
				break;
			}

			sprintf(str,"sbbsexec_hungup%d",node_num);
			hungup_event=OpenEvent(
				EVENT_ALL_ACCESS,	/* access flag  */
				FALSE,				/* inherit flag  */
				str);				/* pointer to event-object name  */
			if(hungup_event==NULL) {
				lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s"
					,GetLastError(),str);
				retval=4;
				break;
			}

			sprintf(str,"sbbsexec_hangup%d",node_num);
			hangup_event=OpenEvent(
				EVENT_ALL_ACCESS,	/* access flag  */
				FALSE,				/* inherit flag  */
				str);				/* pointer to event-object name  */
			if(hangup_event==NULL) {
				lprintf(LOG_WARNING,"!VDD_OPEN: Error %d opening %s"
					,GetLastError(),str);
			}

			status_poll=0;
			inbuf_poll=0;
			online_poll=0;
			yields=0;

			lprintf(LOG_INFO,"Yield interval: %f milliseconds", yield_interval);

			if(virtualize_uart) {
				lprintf(LOG_INFO,"Virtualizing UART (0x%x, IRQ %u)"
					,uart_io_base, uart_irq);

				IOHandlers.inb_handler = uart_rdport;
				IOHandlers.outb_handler = uart_wrport;
				PortRange.First=uart_io_base;
				PortRange.Last=uart_io_base + UART_IO_RANGE;

				VDDInstallIOHook((HANDLE)getAX(), 1, &PortRange, &IOHandlers);

				interrupt_event=CreateEvent(NULL,FALSE,FALSE,NULL);
				InitializeCriticalSection(&interrupt_mutex);

				_beginthread(interrupt_thread, 0, NULL);
			}

			lprintf(LOG_DEBUG,"VDD_OPEN: Opened successfully (wrslot=%p)", wrslot);

			_beginthread(input_thread, 0, NULL);

			retval=0;
			break;

		case VDD_CLOSE:
			lprintf(LOG_INFO,"VDD_CLOSE: rdbuf=%u "
				"status_poll=%u inbuf_poll=%u online_poll=%u yields=%u vdd_yields=%u vdd_calls=%u"
				,RingBufFull(&rdbuf),status_poll,inbuf_poll,online_poll
				,yields,vdd_yields,vdd_calls);
			lprintf(LOG_INFO,"           read=%u bytes (in %u calls)",bytes_read,reads);
			lprintf(LOG_INFO,"           wrote=%u bytes (in %u calls)",bytes_written,writes);

			if(virtualize_uart) {
				lprintf(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook");
				VDDDeInstallIOHook((HANDLE)getAX(), 1, &PortRange);
			}

			CloseHandle(rdslot);
			CloseHandle(wrslot);
			if(hungup_event!=NULL)
				CloseHandle(hungup_event);
			if(hangup_event!=NULL)
				CloseHandle(hangup_event);

#if 0	/* This isn't strictly necessary... 
		   and possibly the cause of a NULL dereference in the input_thread */
			RingBufDispose(&rdbuf);
#endif
			status_poll=0;
			retval=0;

			break;

		case VDD_READ:
			count = getCX();
			if(count != 1)
				lprintf(LOG_DEBUG,"VDD_READ of %d",count);
			p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 
			retval=vdd_read(p, count);
			reads++;
			bytes_read+=retval;
			reset_yield();
			break;

		case VDD_PEEK:
			count = getCX();
			if(count != 1)
				lprintf(LOG_DEBUG,"VDD_PEEK of %d",count);

			p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 
			retval=RingBufPeek(&rdbuf,p,count);
			reset_yield();
			break;

		case VDD_WRITE:
			count = getCX();
			if(count != 1)
				lprintf(LOG_DEBUG,"VDD_WRITE of %d",count);
			p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 
			if(!WriteFile(wrslot,p,count,&retval,NULL)) {
				lprintf(LOG_ERR,"!VDD_WRITE: WriteFile Error %d (size=%d)"
					,GetLastError(),retval);
				retval=0;
			} else {
				writes++;
				bytes_written+=retval;
				reset_yield();
			}
			break;

		case VDD_STATUS:

			status_poll++;
			count = getCX();
			if(count != sizeof(vdd_status_t)) {
				lprintf(LOG_DEBUG,"!VDD_STATUS: wrong size (%d!=%d)",count,sizeof(vdd_status_t));
				retval=sizeof(vdd_status_t);
				break;
			}
			status = (vdd_status_t*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 

			status->inbuf_size=RINGBUF_SIZE_IN;
			status->inbuf_full=RingBufFull(&rdbuf);
			msgs=0;

			/* OUTBUF FULL/SIZE */
			if(!GetMailslotInfo(
				wrslot,					/* mailslot handle  */
 				&status->outbuf_size,	/* address of maximum message size  */
				&status->outbuf_full,	/* address of size of next message  */
				&msgs,					/* address of number of messages  */
 				NULL					/* address of read time-out  */
				)) {
				lprintf(LOG_ERR,"!VDD_STATUS: GetMailSlotInfo(%p) failed, error %u (msgs=%u, inbuf_full=%u, inbuf_size=%u)"
					,wrslot
					,GetLastError(), msgs, status->inbuf_full, status->inbuf_size);
				status->outbuf_full=0;
				status->outbuf_size=DEFAULT_MAX_MSG_SIZE;
			} else
				lprintf(LOG_DEBUG,"VDD_STATUS: MailSlot maxmsgsize=%u, nextmsgsize=%u, msgs=%u"
					,status->outbuf_size
					,status->outbuf_full
					,msgs);
			if(status->outbuf_full==MAILSLOT_NO_MESSAGE)
				status->outbuf_full=0;
			status->outbuf_full*=msgs;
			
			/* ONLINE */
			if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
				status->online=0;
			else
				status->online=1;

			retval=0;	/* success */
			break;

		case VDD_INBUF_PURGE:
			RingBufReInit(&rdbuf);
			retval=0;
			break;

		case VDD_OUTBUF_PURGE:
			lprintf(LOG_WARNING,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED");
			retval=0;
			break;

		case VDD_INBUF_FULL:
			retval=RingBufFull(&rdbuf);
			inbuf_poll++;
			break;

		case VDD_INBUF_SIZE:
			retval=RINGBUF_SIZE_IN;
			break;

		case VDD_OUTBUF_FULL:
			if(!GetMailslotInfo(
				wrslot,		/* mailslot handle  */
 				NULL,		/* address of maximum message size  */
				&retval,	/* address of size of next message  */
				&msgs,		/* address of number of messages  */
 				NULL		/* address of read time-out  */
				))
				retval=0;
			if(retval==MAILSLOT_NO_MESSAGE)
				retval=0;
			retval*=msgs;
			break;

		case VDD_OUTBUF_SIZE:
			if(!GetMailslotInfo(
				wrslot,		/* mailslot handle  */
 				&retval,	/* address of maximum message size  */
				NULL,		/* address of size of next message  */
				NULL,		/* address of number of messages  */
 				NULL		/* address of read time-out  */
				)) 
				retval=DEFAULT_MAX_MSG_SIZE;
			break;

		case VDD_ONLINE:
			if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
				retval=0;
			else
				retval=1;
			online_poll++;
			break;

		case VDD_YIELD:			/* forced yield */
			vdd_yields++;
			yield();
			break;

		case VDD_MAYBE_YIELD:	/* yield if YieldInterval is enabled and expired */
			maybe_yield();
			break;

		case VDD_LOAD_INI_FILE:	/* Load and parse settings file */
			{
				FILE*	fp;
				char	cwd[MAX_PATH+1];

				/* Load exec/sbbsexec.ini first (setting default values) */
				count = getCX();
				p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI())
					,count,FALSE); 
				iniFileName(ini_fname, sizeof(ini_fname), p, INI_FILENAME);
				if((fp=fopen(ini_fname,"r"))!=NULL) {
					ini=iniReadFile(fp);
					fclose(fp);
					parse_ini(ROOT_SECTION);
				}

				/* Load cwd/sbbsexec.ini second (over-riding default values) */
				GetCurrentDirectory(sizeof(cwd),cwd);
				iniFileName(ini_fname, sizeof(ini_fname), cwd, INI_FILENAME);
				if((fp=fopen(ini_fname,"r"))!=NULL) {
					ini=iniReadFile(fp);
					fclose(fp);
					parse_ini(ROOT_SECTION);
				}
			}
			break;

		case VDD_LOAD_INI_SECTION:	/* Parse (program-specific) sub-section of settings file */
			count = getCX();
			p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 
			parse_ini(p);
			break;

		case VDD_DEBUG_OUTPUT:	/* Send string to debug output */
			count = getCX();
			p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI())
				,count,FALSE); 
			lputs(LOG_INFO, p);
			break;

		case VDD_HANGUP:
			hangup();
			break;

		default:
			lprintf(LOG_ERR,"!UNKNOWN VDD_OP: %d",getBL());
			break;
	}
	setAX((WORD)retval);
}
Пример #23
0
void oCourse::lastAsFinish(bool f) {
  getDI().setInt("LastAsFinish", f ? 1:0);
}
Пример #24
0
void oCourse::firstAsStart(bool f) {
  getDI().setInt("FirstAsStart", f ? 1:0);
}
Пример #25
0
VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        /* RegisterModule */
        case 0:
        {
            BOOL Success = TRUE;
            WORD RetVal  = 0;
            WORD Entry   = 0;
            LPCSTR DllName = NULL,
                   InitRoutineName     = NULL,
                   DispatchRoutineName = NULL;
            HMODULE hDll = NULL;
            VDD_PROC InitRoutine     = NULL,
                     DispatchRoutine = NULL;

            DPRINT("RegisterModule() called\n");

            /* Clear the Carry Flag (no error happened so far) */
            setCF(0);

            /* Retrieve the next free entry in the table (used later on) */
            Entry = GetNextFreeVDDEntry();
            if (Entry >= MAX_VDD_MODULES)
            {
                DPRINT1("Failed to create a new VDD module entry\n");
                Success = FALSE;
                RetVal = 4;
                goto Quit;
            }

            /* Retrieve the VDD name in DS:SI */
            DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());

            /* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */
            if (TO_LINEAR(getES(), getDI()) != 0)
                InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI());

            /* Retrieve the dispatch routine API name in DS:BX */
            DispatchRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getBX());

            DPRINT1("DllName = '%s' - InitRoutineName = '%s' - DispatchRoutineName = '%s'\n",
                    (DllName ? DllName : "n/a"),
                    (InitRoutineName ? InitRoutineName : "n/a"),
                    (DispatchRoutineName ? DispatchRoutineName : "n/a"));

            /* Load the VDD DLL */
            hDll = LoadLibraryA(DllName);
            if (hDll == NULL)
            {
                DWORD LastError = GetLastError();
                Success = FALSE;

                if (LastError == ERROR_NOT_ENOUGH_MEMORY)
                {
                    DPRINT1("Not enough memory to load DLL '%s'\n", DllName);
                    RetVal = 4;
                    goto Quit;
                }
                else
                {
                    DPRINT1("Failed to load DLL '%s'; last error = %d\n", DllName, LastError);
                    RetVal = 1;
                    goto Quit;
                }
            }

            /* Load the initialization routine if needed */
            if (InitRoutineName)
            {
                InitRoutine = (VDD_PROC)GetProcAddress(hDll, InitRoutineName);
                if (InitRoutine == NULL)
                {
                    DPRINT1("Failed to load the initialization routine '%s'\n", InitRoutineName);
                    Success = FALSE;
                    RetVal = 3;
                    goto Quit;
                }
            }

            /* Load the dispatch routine */
            DispatchRoutine = (VDD_PROC)GetProcAddress(hDll, DispatchRoutineName);
            if (DispatchRoutine == NULL)
            {
                DPRINT1("Failed to load the dispatch routine '%s'\n", DispatchRoutineName);
                Success = FALSE;
                RetVal = 2;
                goto Quit;
            }

            /* If we arrived there, that means everything is OK */

            /* Register the VDD DLL */
            VDDList[Entry].hDll = hDll;
            VDDList[Entry].DispatchRoutine = DispatchRoutine;

            /* Call the initialization routine if needed */
            if (InitRoutine) InitRoutine();

            /* We succeeded. RetVal will contain a valid VDD DLL handle */
            Success = TRUE;
            RetVal  = ENTRY_TO_HANDLE(Entry); // Convert the entry to a valid handle

Quit:
            if (!Success)
            {
                /* Unload the VDD DLL */
                if (hDll) FreeLibrary(hDll);

                /* Set the Carry Flag to indicate that an error happened */
                setCF(1);
            }
            // else
            // {
                // /* Clear the Carry Flag (success) */
                // setCF(0);
            // }
            setAX(RetVal);
            break;
        }

        /* UnRegisterModule */
        case 1:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("UnRegisterModule() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle) || VDDList[Entry].hDll == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Unregister the VDD DLL */
            FreeLibrary(VDDList[Entry].hDll);
            VDDList[Entry].hDll = NULL;
            VDDList[Entry].DispatchRoutine = NULL;
            break;
        }

        /* DispatchCall */
        case 2:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("DispatchCall() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle)    ||
                VDDList[Entry].hDll == NULL ||
                VDDList[Entry].DispatchRoutine == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Call the dispatch routine */
            VDDList[Entry].DispatchRoutine();
            break;
        }

        default:
        {
            DPRINT1("Unknown 3rd-party VDD BOP Function: 0x%02X\n", FuncNum);
            setCF(1);
            break;
        }
    }
}
Пример #26
0
void ISV_RegisterModule (BOOL fMode)
{
    char *pchDll,*pchInit,*pchDispatch;
    HANDLE hDll;
    FARPROC DispatchEntry;
    FARPROC InitEntry;
    ULONG i;
    UCHAR uchMode;

    // Check if we have free space in bop table.
    for (i=0; i<MAX_ISV_BOP; i++) {
    if (isvbop_table[i].hDll == 0)
        break;
    }

    if (i == MAX_ISV_BOP) {
    setCF (1);
    setAX(4);
    return;
    }

    uchMode = fMode ? TRUE : FALSE;

    pchDll = (PCHAR) Sim32GetVDMPointer (SEGOFF(getDS(),getSI()),
                                         1,
                                         uchMode
                                         );
    if (pchDll == NULL) {
    setCF (1);
    setAX(1);
    return;
    }
    pchInit = (PCHAR) Sim32GetVDMPointer(SEGOFF(getES(),getDI()),
                                         1,
                                         uchMode
                                         );

    pchDispatch = (PCHAR) Sim32GetVDMPointer(SEGOFF(getDS(),getBX()),
                                             1,
                                             uchMode
                                             );
    if (pchDispatch == NULL) {
    setCF (1);
    setAX(2);
    return;
    }

    if ((hDll = SafeLoadLibrary(pchDll)) == NULL){
    setCF (1);
    setAX(1);
    return;
    }

    // Get the init entry point and dispatch entry point
    if (pchInit){
    if ((ULONG)pchInit < 64*1024){
        if (strlen (pchInit) >= MAX_PROC_NAME) {
        FreeLibrary(hDll);
        setCF (1);
        setAX(4);
        return;
        }
        strcpy (procbuffer,pchInit);
        pchInit = procbuffer;
    }

    if ((InitEntry = (MYFARPROC)GetProcAddress(hDll, pchInit)) == NULL){
        FreeLibrary(hDll);
        setCF(1);
        setAX(3);
            return;
    }
    }

    if ((ULONG)pchDispatch < 64*1024){
    if (strlen (pchDispatch) >= MAX_PROC_NAME) {
        FreeLibrary(hDll);
        setCF (1);
        setAX(4);
        return;
    }
    strcpy (procbuffer,pchDispatch);
    pchDispatch = procbuffer;
    }

    if ((DispatchEntry = (MYFARPROC)GetProcAddress(hDll, pchDispatch)) == NULL){
    FreeLibrary(hDll);
    setCF(1);
    setAX(2);
    return;
    }

    // Call the init routine
    if (pchInit) {
    (*InitEntry)();
    }

    // Fill up the bop table
    isvbop_table[i].hDll = hDll;
    isvbop_table[i].fpDispatch = DispatchEntry;

    i++;

    setAX((USHORT)i);

    return;
}
Пример #27
0
void oCourse::setMinimumRogainingPoints(int p)
{
  cachedHasRogaining = 0;
  getDI().setInt("RPointLimit", p);
}
Пример #28
0
void oCourse::setRogainingPointsPerMinute(int p)
{
  getDI().setInt("RReduction", p);
}
Пример #29
0
oClub::oClub(oEvent *poe): oBase(poe)
{
  getDI().initData();
  Id=oe->getFreeClubId();
}
Пример #30
0
static VOID WINAPI EmsIntHandler(LPWORD Stack)
{
    switch (getAH())
    {
        /* Get Manager Status */
        case 0x40:
        {
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Page Frame Segment */
        case 0x41:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(EmsSegment);
            break;
        }

        /* Get Number of Unallocated Pages */
        case 0x42:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(RtlNumberOfClearBits(&AllocBitmap));
            setDX(EmsTotalPages);
            break;
        }

        /* Get Handle and Allocate Memory */
        case 0x43:
        {
            USHORT Handle;
            UCHAR Status = EmsAlloc(getBX(), &Handle);

            if (Status == EMS_STATUS_SUCCESS)
                setDX(Handle);

            setAH(Status);
            break;
        }

        /* Map Memory */
        case 0x44:
        {
            setAH(EmsMap(getDX(), getAL(), getBX()));
            break;
        }

        /* Release Handle and Memory */
        case 0x45:
        {
            setAH(EmsFree(getDX()));
            break;
        }

        /* Get EMM Version */
        case 0x46:
        {
            setAH(EMS_STATUS_SUCCESS);
            setAL(EMS_VERSION_NUM);
            break;
        }

        /* Save Page Map */
        case 0x47:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(MappingBackup, Mapping, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Restore Page Map */
        case 0x48:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(Mapping, MappingBackup, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Number of Opened Handles */
        case 0x4B:
        {
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                    ++NumOpenHandles;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get Handle Number of Pages */
        case 0x4C:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(HandleEntry->PageCount);
            break;
        }

        /* Get All Handles Number of Pages */
        case 0x4D:
        {
            PEMS_HANDLE_PAGE_INFO HandlePageInfo = (PEMS_HANDLE_PAGE_INFO)SEG_OFF_TO_PTR(getES(), getDI());
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                {
                    HandlePageInfo->Handle = i;
                    HandlePageInfo->PageCount = HandleTable[i].PageCount;
                    ++HandlePageInfo;
                    ++NumOpenHandles;
                }
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get or Set Page Map */
        case 0x4E:
        {
            switch (getAL())
            {
                /* Get Mapping Registers  */
                // case 0x00: // TODO: NOT IMPLEMENTED
 
                /* Set Mapping Registers */
                // case 0x01: // TODO: NOT IMPLEMENTED

                /* Get and Set Mapping Registers At Once */
                // case 0x02: // TODO: NOT IMPLEMENTED

                /* Get Size of Page-Mapping Array */
                case 0x03:
                {
                    setAH(EMS_STATUS_SUCCESS);
                    setAL(sizeof(Mapping));
                    break;
                }

                default:
                {
                    DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL());
                    setAH(EMS_STATUS_UNKNOWN_FUNCTION);
                    break;
                }
            }
            
            break;
        }

        /* Get/Set Handle Name */
        case 0x53:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            if (getAL() == 0x00)
            {
                /* Retrieve the name */
                RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
                              HandleEntry->Name,
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else if (getAL() == 0x01)
            {
                /* Store the name */
                RtlCopyMemory(HandleEntry->Name,
                              SEG_OFF_TO_PTR(getDS(), getSI()),
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Handle Directory functions */
        case 0x54:
        {
            if (getAL() == 0x00)
            {
                /* Get Handle Directory */

                PEMS_HANDLE_DIR_ENTRY HandleDir = (PEMS_HANDLE_DIR_ENTRY)SEG_OFF_TO_PTR(getES(), getDI());
                USHORT NumOpenHandles = 0;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated)
                    {
                        HandleDir->Handle = i;
                        RtlCopyMemory(HandleDir->Name,
                                      HandleTable[i].Name,
                                      sizeof(HandleDir->Name));
                        ++HandleDir;
                        ++NumOpenHandles;
                    }
                }

                setAH(EMS_STATUS_SUCCESS);
                setAL((UCHAR)NumOpenHandles);
            }
            else if (getAL() == 0x01)
            {
                /* Search for Named Handle */

                PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
                PEMS_HANDLE HandleFound = NULL;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated &&
                        RtlCompareMemory(HandleName,
                                         HandleTable[i].Name,
                                         sizeof(HandleTable[i].Name)) == sizeof(HandleTable[i].Name))
                    {
                        HandleFound = &HandleTable[i];
                        break;
                    }
                }

                /* Bail out if no handle was found */
                if (i >= ARRAYSIZE(HandleTable)) // HandleFound == NULL
                {
                    setAH(EMS_STATUS_HANDLE_NOT_FOUND);
                    break;
                }

                /* Return the handle number */
                setDX(i);

                /* Sanity check: Check whether the handle was unnamed */
                i = 0;
                while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0'))
                    ++i;

                if (i >= sizeof(HandleFound->Name))
                {
                    setAH(EMS_STATUS_UNNAMED_HANDLE);
                }
                else
                {
                    setAH(EMS_STATUS_SUCCESS);
                }
            }
            else if (getAL() == 0x02)
            {
                /*
                 * Get Total Number of Handles
                 *
                 * This function retrieves the maximum number of handles
                 * (allocated or not) the memory manager supports, which
                 * a program may request.
                 */
                setAH(EMS_STATUS_SUCCESS);
                setBX(ARRAYSIZE(HandleTable));
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Move/Exchange Memory */
        case 0x57:
        {
            PUCHAR SourcePtr, DestPtr;
            PEMS_HANDLE HandleEntry;
            PEMS_PAGE PageEntry;
            BOOLEAN Exchange = getAL();
            PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());

            if (Data->SourceType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->SourceHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                     + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                     + Data->SourceOffset);
            }
            else
            {
                /* Conventional memory */
                SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
            }

            if (Data->DestType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->DestHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                   + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                   + Data->DestOffset);
            }
            else
            {
                /* Conventional memory */
                DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
            }

            if (Exchange)
            {
                ULONG i;

                /* Exchange */
                for (i = 0; i < Data->RegionLength; i++)
                {
                    UCHAR Temp = DestPtr[i];
                    DestPtr[i] = SourcePtr[i];
                    SourcePtr[i] = Temp;
                }
            }
            else
            {
                /* Move */
                RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
            }

            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Mappable Physical Address Array */
        case 0x58:
        {
            if (getAL() == 0x00)
            {
                PEMS_MAPPABLE_PHYS_PAGE PageArray = (PEMS_MAPPABLE_PHYS_PAGE)SEG_OFF_TO_PTR(getES(), getDI());
                ULONG i;

                for (i = 0; i < EMS_PHYSICAL_PAGES; i++)
                {
                    PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4);
                    PageArray->PageNumber  = i;
                    ++PageArray;
                }

                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else if (getAL() == 0x01)
            {
                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }