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; }
static VOID CmdStartExternalCommand(VOID) { DWORD Result; // TODO: improve: this code has strong similarities // with the 'default' case of DosCreateProcess. LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI()); CHAR CmdLine[sizeof("cmd.exe /c ") + DOS_CMDLINE_LENGTH + 1] = ""; LPSTR CmdLinePtr; ULONG CmdLineLen; /* Spawn a user-defined 32-bit command preprocessor */ // FIXME: Use COMSPEC env var!! CmdLinePtr = CmdLine; strcpy(CmdLinePtr, "cmd.exe /c "); CmdLinePtr += strlen(CmdLinePtr); /* Build a Win32-compatible command-line */ CmdLineLen = min(strlen(Command), sizeof(CmdLine) - strlen(CmdLinePtr) - 1); RtlCopyMemory(CmdLinePtr, Command, CmdLineLen); CmdLinePtr[CmdLineLen] = '\0'; /* Remove any trailing return carriage character and NULL-terminate the command line */ while (*CmdLinePtr && *CmdLinePtr != '\r' && *CmdLinePtr != '\n') CmdLinePtr++; *CmdLinePtr = '\0'; DPRINT1("CMD Run Command '%s' ('%s')\n", Command, CmdLine); /* * No need to prepare the stack for DosStartComSpec since we won't start it. */ Result = DosStartProcess32(Command, CmdLine, SEG_OFF_TO_PTR(getES(), 0) /*Environment*/, MAKELONG(getIP(), getCS()) /*ReturnAddress*/, FALSE); if (Result != ERROR_SUCCESS) { DosDisplayMessage("Failed to start command '%s' ('%s'). Error: %u\n", Command, CmdLine, Result); setCF(0); setAL((UCHAR)Result); } else { DosDisplayMessage("Command '%s' ('%s') started successfully.\n", Command, CmdLine); #ifndef STANDALONE setCF(Repeat); // Set CF if we need to start a 16-bit process #else setCF(0); #endif } }
void convertNV21toRGB(unsigned char *b, int w, int h, int *idata, unsigned short *sdata) { int i,j; int y=0; int uo=w*h; int o=0; int u,v; int strideuv=w; if(sdata && idata) { for(j=0; j<h; j++) { uo=w*h+(j/2)*strideuv; for(i=0; i<w; i+=2) { u=b[uo]; v=b[uo+1]; getSI(sdata[o],idata[o],b[y],u,v); y++; o++; getSI(sdata[o],idata[o],b[y],u,v); y++; o++; uo+=2; } } } else if(idata) { for(j=0; j<h; j++) { uo=w*h+(j/2)*strideuv; for(i=0; i<w; i+=2) { u=b[uo]; v=b[uo+1]; idata[o]=getInt(b[y],u,v); y++; o++; idata[o]=getInt(b[y],u,v); y++; o++; uo+=2; } } } }
VOID cmdExec (VOID) { DWORD i; DWORD dwRet; PCHAR pCommandTail; PCHAR pEnv; CHAR Buffer[MAX_PATH]; pCommandTail = (PCHAR) GetVDMAddr ((USHORT)getDS(),(USHORT)getSI()); pEnv = (PCHAR) GetVDMAddr ((USHORT)getES(),0); for (i=0 ; i<124 ; i++) { if (pCommandTail[i] == 0x0d){ pCommandTail[i] = 0; break; } } if (i == 124){ setCF(0); setAL((UCHAR)ERROR_BAD_FORMAT); return; } chDefaultDrive = (CHAR)(getAL() + 'A'); if (getAH() == 0) { cmdExec32 (pCommandTail,pEnv); } else { dwRet = GetEnvironmentVariable ("COMSPEC",Buffer,MAX_PATH); if (dwRet == 0 || dwRet >= MAX_PATH){ setCF(0); setAL((UCHAR)ERROR_BAD_ENVIRONMENT); return; } if ((dwRet + 4 + strlen(pCommandTail)) > MAX_PATH) { setCF(0); setAL((UCHAR)ERROR_BAD_ENVIRONMENT); return; } strcat (Buffer, " /c "); strcat (Buffer, pCommandTail); cmdExec32 (Buffer,pEnv); } return; }
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; }
static VOID WINAPI DosCmdInterpreterBop(LPWORD Stack) { /* Get the Function Number and skip it */ BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP()); setIP(getIP() + 1); switch (FuncNum) { case 0x08: // Launch external command { #define CMDLINE_LENGTH 1024 BOOL Result; DWORD dwExitCode; LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI()); LPSTR CmdPtr = Command; CHAR CommandLine[CMDLINE_LENGTH] = ""; STARTUPINFOA StartupInfo; PROCESS_INFORMATION ProcessInformation; /* NULL-terminate the command line by removing the return carriage character */ while (*CmdPtr && *CmdPtr != '\r') CmdPtr++; *CmdPtr = '\0'; DPRINT1("CMD Run Command '%s'\n", Command); /* Spawn a user-defined 32-bit command preprocessor */ /* Build the command line */ // FIXME: Use COMSPEC env var!! strcpy(CommandLine, "cmd.exe /c "); strcat(CommandLine, Command); ZeroMemory(&StartupInfo, sizeof(StartupInfo)); ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); StartupInfo.cb = sizeof(StartupInfo); VidBiosDetachFromConsole(); Result = CreateProcessA(NULL, CommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation); if (Result) { DPRINT1("Command '%s' launched successfully\n", Command); /* Wait for process termination */ WaitForSingleObject(ProcessInformation.hProcess, INFINITE); /* Get the exit code */ GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode); /* Close handles */ CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); } else { DPRINT1("Failed when launched command '%s'\n"); dwExitCode = GetLastError(); } VidBiosAttachToConsole(); setAL((UCHAR)dwExitCode); break; } default: { DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum); // setCF(1); // Disable, otherwise we enter an infinite loop break; } } }
static VOID WINAPI XmsBopProcedure(LPWORD Stack) { switch (getAH()) { /* Get XMS Version */ case 0x00: { setAX(0x0300); /* XMS version 3.00 */ setBX(0x0301); /* Driver version 3.01 */ setDX(0x0001); /* HMA present */ break; } /* Request HMA */ case 0x01: { /* Check whether HMA is already reserved */ if (IsHmaReserved) { /* It is, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_IN_USE); break; } // NOTE: We implicitely suppose that we always have HMA. // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST // error code. /* Check whether the requested size is above the minimal allowed one */ if (getDX() < HmaMinSize) { /* It is not, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_MIN_SIZE); break; } /* Reserve it */ IsHmaReserved = TRUE; setAX(0x0001); setBL(XMS_STATUS_SUCCESS); break; } /* Release HMA */ case 0x02: { /* Check whether HMA was reserved */ if (!IsHmaReserved) { /* It was not, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_NOT_ALLOCATED); break; } /* Release it */ IsHmaReserved = FALSE; setAX(0x0001); setBL(XMS_STATUS_SUCCESS); break; } /* Global Enable A20 */ case 0x03: { /* Enable A20 if needed */ if (!IsA20Enabled) { XmsLocalEnableA20(); if (getAX() != 0x0001) { /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */ break; } IsA20Enabled = TRUE; } setAX(0x0001); /* Line successfully enabled */ setBL(XMS_STATUS_SUCCESS); break; } /* Global Disable A20 */ case 0x04: { UCHAR Result = XMS_STATUS_SUCCESS; /* Disable A20 if needed */ if (IsA20Enabled) { XmsLocalDisableA20(); if (getAX() != 0x0001) { /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */ break; } IsA20Enabled = FALSE; Result = getBL(); } setAX(0x0001); /* Line successfully disabled */ setBL(Result); break; } /* Local Enable A20 */ case 0x05: { /* This call sets AX and BL to their correct values */ XmsLocalEnableA20(); break; } /* Local Disable A20 */ case 0x06: { /* This call sets AX and BL to their correct values */ XmsLocalDisableA20(); break; } /* Query A20 State */ case 0x07: { setAX(EmulatorGetA20()); setBL(XMS_STATUS_SUCCESS); break; } /* Query Free Extended Memory */ case 0x08: { setAX(XmsGetLargestFreeBlock()); setDX(FreeBlocks); if (FreeBlocks > 0) setBL(XMS_STATUS_SUCCESS); else setBL(XMS_STATUS_OUT_OF_MEMORY); break; } /* Allocate Extended Memory Block */ case 0x09: { WORD Handle; UCHAR Result = XmsAlloc(getDX(), &Handle); if (Result == XMS_STATUS_SUCCESS) { setAX(1); setDX(Handle); } else { setAX(0); setBL(Result); } break; } /* Free Extended Memory Block */ case 0x0A: { UCHAR Result = XmsFree(getDX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Move Extended Memory Block */ case 0x0B: { PVOID SourceAddress, DestAddress; PXMS_COPY_DATA CopyData = (PXMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI()); PXMS_HANDLE HandleEntry; if (CopyData->SourceHandle) { HandleEntry = GetHandleRecord(CopyData->SourceHandle); if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_BAD_SRC_HANDLE); break; } if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE) { setAX(0); setBL(XMS_STATUS_BAD_SRC_OFFSET); } SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset); } else { /* The offset is actually a 16-bit segment:offset pointer */ SourceAddress = FAR_POINTER(CopyData->SourceOffset); } if (CopyData->DestHandle) { HandleEntry = GetHandleRecord(CopyData->DestHandle); if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_BAD_DEST_HANDLE); break; } if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE) { setAX(0); setBL(XMS_STATUS_BAD_DEST_OFFSET); } DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset); } else { /* The offset is actually a 16-bit segment:offset pointer */ DestAddress = FAR_POINTER(CopyData->DestOffset); } /* Perform the move */ RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count); setAX(1); setBL(XMS_STATUS_SUCCESS); break; } /* Lock Extended Memory Block */ case 0x0C: { DWORD Address; UCHAR Result = XmsLock(getDX(), &Address); if (Result == XMS_STATUS_SUCCESS) { setAX(1); /* Store the LINEAR address in DX:BX */ setDX(HIWORD(Address)); setBX(LOWORD(Address)); } else { setAX(0); setBL(Result); } break; } /* Unlock Extended Memory Block */ case 0x0D: { UCHAR Result = XmsUnlock(getDX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Get Handle Information */ case 0x0E: { PXMS_HANDLE HandleEntry = GetHandleRecord(getDX()); UINT i; UCHAR Handles = 0; if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_INVALID_HANDLE); break; } for (i = 0; i < XMS_MAX_HANDLES; i++) { if (HandleTable[i].Handle == 0) Handles++; } setAX(1); setBH(HandleEntry->LockCount); setBL(Handles); setDX(HandleEntry->Size); break; } /* Reallocate Extended Memory Block */ case 0x0F: { UCHAR Result = XmsRealloc(getDX(), getBX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Request UMB */ case 0x10: { BOOLEAN Result; USHORT Segment = 0x0000; /* No preferred segment */ USHORT Size = getDX(); /* Size is in paragraphs */ Result = UmaDescReserve(&Segment, &Size); if (Result) setBX(Segment); else setBL(Size > 0 ? XMS_STATUS_SMALLER_UMB : XMS_STATUS_OUT_OF_UMBS); setDX(Size); setAX(Result); break; } /* Release UMB */ case 0x11: { BOOLEAN Result; USHORT Segment = getDX(); Result = UmaDescRelease(Segment); if (!Result) setBL(XMS_STATUS_INVALID_UMB); setAX(Result); break; } /* Reallocate UMB */ case 0x12: { BOOLEAN Result; USHORT Segment = getDX(); USHORT Size = getBX(); /* Size is in paragraphs */ Result = UmaDescReallocate(Segment, &Size); if (!Result) { if (Size > 0) { setBL(XMS_STATUS_SMALLER_UMB); setDX(Size); } else { setBL(XMS_STATUS_INVALID_UMB); } } setAX(Result); break; } default: { DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH()); setBL(XMS_STATUS_NOT_IMPLEMENTED); } } }
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; } } }
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; }
void printer_io() { #ifdef PRINTER half_word time_out, status; word printer_io_address, printer_io_reg, printer_status_reg, printer_control_reg; boolean printer_busy = TRUE; unsigned long time_count; int adapter; #ifdef NTVDM int bopsubfunction = getSI(); switch (bopsubfunction) { #ifdef MONITOR case 0: /* this is the bop to flush 16bit printer buffer */ printer_bop_flush (); return; #endif case 1: case 2: /* this is the bop to track a DOS open/close on LPTn */ printer_bop_openclose (bopsubfunction); return; } #endif setIF(1); adapter = getDX() % NUM_PARALLEL_PORTS; sas_loadw(port_address[adapter], &printer_io_address); printer_io_reg = printer_io_address; printer_status_reg = printer_io_address + 1; printer_control_reg = printer_io_address + 2; sas_load(timeout_address[adapter], &time_out); time_count = time_out * 0xFFFF; if (printer_io_address != 0) { IDLE_comlpt (); switch(getAH()) { case 0: /* Check the port status for busy before sending the character*/ while(printer_busy && time_count > 0) { /* The host_lpt_status() should check for status changes */ /* possibly by calling AsyncEventManager() if it's using */ /* XON /XOFF flow control. */ inb(printer_status_reg, &status); if (status & 0x80) printer_busy = FALSE; else time_count--; } if (printer_busy) { status &= 0xF8; /* clear bottom unused bits */ status |= 1; /* set error flag */ } else { /* Only send the character if the port isn't still busy */ outb(printer_io_reg, getAL()); outb(printer_control_reg, 0x0D); /* strobe low-high */ outb(printer_control_reg, 0x0C); /* strobe high-low */ inb(printer_status_reg, &status); status &= 0xF8; /* clear unused bits */ } status ^= 0x48; /* flip the odd bit */ setAH(status); break; case 1: outb(printer_control_reg, 0x08); /* set init line low */ outb(printer_control_reg, 0x0C); /* set init line high */ inb(printer_status_reg, &status); status &= 0xF8; /* clear unused bits */ status ^= 0x48; /* flip the odd bit */ setAH(status); break; case 2: inb(printer_status_reg, &status); status &= 0xF8; /* clear unused bits */ status ^= 0x48; /* flip the odd bit */ setAH(status); break; default: break; } } #endif }
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; }