⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dos386c.c

📁 arm-linux-gcc编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * Copyright 1991 Advanced Micro Devices, Inc. * * This software is the property of Advanced Micro Devices, Inc  (AMD)  which * specifically  grants the user the right to modify, use and distribute this * software provided this notice is not removed or altered.  All other rights * are reserved by AMD. * * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR * USE OF THIS SOFTWARE. * * Comments about this software should be directed to udi@amd.com. If access * to electronic mail isn't available, send mail to: * * Advanced Micro Devices, Inc. * 29K Support Products * Mail Stop 573 * 5900 E. Ben White Blvd. * Austin, TX 78741 ***************************************************************************** *       $Id: dos386c.c,v 1.2 1993/12/23 04:44:41 cassidy Exp $ *       $Id: @(#)dos386c.c	1.9, AMD *//* DOS386 specific constructs and functions.  These assume the use of * the 386|DOS-Extender from Pharlap. * * This file contains functions which serve as an intermediate between * protected mode UDI function calls made by the DFE and the possibly * real-mode function called in the TIP.  These functions assume that * the interface between the TIP and the DFE is real-mode and that the * DFE is protected mode, flat model (32 bit linear addresses). * * Note: * This code allocates a section of real-mode memory using * a call to _dx_real_alloc.  Protected mode far pointers (48-bit) * must be used to access this memory area. * * For every UDI function named UDIx..x, there is a function in this * module named UDIPx..x, where the "P" indicates that this is a protected * mode interface function.  A protected mode DFE needs to call the * UDIPx..x equivalent of the call to the TIP UDI function.  The call * parameters are the same as the UDI call except that the address of the * TIP UDI function is always the first parameter to the UDIPx..x  * function. * * Each function follows the format outlined below: * * UDIError UDIPx..x(REALPTR function_address [, UDI function parameters]) * { * 	Allocate pointers into the conventional memory area used for *		parameter passing (PPM) for all parameters which are *		passed-by-reference.  Each of these pointers is given *		the same name as a parameter with "Ptr" appended to it. * *	Create a packed structure for parameter passing if there is more *		than one parameter to the function.  Each member of this *		structure (always named params) has the same name as the *		corresponding parameter to the UDIP... call. * *	Set the parameter pointers to the appropriate offsets in the PPM. *		The protected mode pointer to the first parameter is always *		rm_address (the real mode equivalent to this pointer is *		rm_buffer_addr). * *	Copy the data from protected mode (possibly extended) memory to *		the location indicated by the correct pointer  * *	Copy the passed-by-value parameters directly into the params *		structure.  Convert the protected mode version of the *		pointers into the PPM area to real-mode pointers and *		assign them to their corresponding params data member. * *	Call the real-mode function, pushing the params structure onto  *		the stack.  Generally this involves the use of the macro *		REALCALL, however functions with no parameters call  *		_dx_call_real explicitly.  The size of the params structure *		is determined by the macro WORDSIZE. * *	Check for an error returned from _dx_call_real.  If there is one *		report it and die (how uncouth!). * *	Copy all "out" parameters into their local (non-conventional  *		memory eqivalents.  In functions with "count" parameters, *		make sure that the count value makes sense and only  *		copy as much as is allowed by the buffer size. *	 *	The return value of the UDI TIP function is in the ax register of *		the regs structure, return this as the value of the UDIP *		function. * } * * * UDIPRead, UDIPWrite, UDIPPutStdOut, UDIPGetStdOut,  * UDIPGetStderr, UDIPPutTrans and UDIPGetTrans differ from the other * UDIP functions in that they allow looping within the UDIP layer * call to the TIP.  This looping is done so that the size of the * real mode buffer area does not limit the size of the data transfer * since all data passed by reference *must* be copied into the real * mode buffer area and the TIP can only return as much information * as can fit in this real mode buffer (unlike the situation for a  * real mode DFE where the DFE and the TIP write to the same memory). * * The calls all use the same logic, outlined below: * * * Set the CurrentCount equal to the total number of items to  * be transfered (CurrentCount = *Count). * * Set the total number of items transfered so far to zero (TotalDone = 0) * * Set up moving pointers into the From and To transfer areas to keep * track of where the current transfer should be read and/or written. * (CurrentTo = To; CurrentFrom = From) * * do  *    Set a pointer to the end of the memory that would be required *    to do the complete transfer. * *    If the pointer is outside of the buffer area (determined by *    call the BufferSizeCheck), then we need to adjust the *    size of the requested transfer. * *       Set the pointer to the last item to the last valid location *       in the real mode buffer area. * *       Set the value of CurrentCount to the maximum number of data *       items that can be transfered, based on the Size parameter. * *    Call the TIP function with CurrentCount instead of *Count, *    CurrentTo instead of To and CurrentFrom instead of From. * *    Set the CurrentDone equal to the CountDone returned by the *    function call. * *    Update the pointers into the From and To transfer areas to the *    end of the just completed transfer (CurrentFrom += CurrentDone *    * Size, CurrentTo += CurrentDone * Size) * *    Increment the TotalDone by the number of items transfered in *    the last call (TotalDone += CurrentDone) * * while transfer is not complete (TotalDone < *Count) * */#define _DOS386C_C#include <dos.h>#include <process.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <udiproc.h>#include <pharlap.h>#include <udidos.h>#include <stdarg.h>#include <dos386c.h>#define REAL_BUFFER_SIZE 0x1000#define PRINT_ON  1#define PRINT_OFF 0#define WORDSIZE(param) ((sizeof(param)/2) + (sizeof(param) %2))#define REALCALL(x,y) _dx_call_real(x, &real_regs, WORDSIZE(y), y)#define FUNC_VAL ((UDIError) real_regs.eax)#define SIZE_ERROR(Done, Size, function_name) printf("Return size (%d) > Buffer size (%d) in function %s\n",Done,Size,function_name)/* * 4/93 MDT * The following defines are used to allow UDI 1.2 functions to identify * themselves to the compiler and the user when UDI 1.3 is defined.  These * are needed to differentiate the 1.2 versions of some functions (UDIPConnect) * from their 1.3 versions. */#if defined __STDC__ || defined _MSC_VER#define XCAT(a,b) a##b#else#define XCAT(a,b) a/**/b#endif#ifdef UDI13 #define UDI12FUNCVER _12#define UDI12FUNCVERSTR " (1.2)"#define CAT(a,b) XCAT(a,b)#else /* not UDI 1.3 */#define UDI12FUNCVER dummy	/* Have to pass two arguments to CAT */ #define UDI12FUNCVERSTR ""#define CAT(a,b) a		/* Don't actually want to concatenate anything */#endif /* UDI 1.3 *//* Needed by call to _dx_real_call, but no values need to be set * since TIP is compiled assuming it doesn't know anything about the * values in the registers. */RMC_BLK  real_regs;	/* Pointers to use for handling conventional memory buffer area.  This * area is used to pass parameters to and from real-mode procedures. */REALPTR	rm_buffer_addr;		/* real-mode pointer to parameter buffer area.     */ULONG		rm_buffer_size;		/* size of paramter buffer area.                   */USHORT _far	*rm_address;		/* pointer to paramter buffer area.                */USHORT _far	*rm_end_address;	/* the last valid address of the parameter buffer  */int		buffer_allocated=0;	/* used to denote that the status of the buffer    */REALPTR PROT_TO_REAL(FARPTR p)		/* converts a PROT ptr to a REALPTR */{REALPTR  dummyrp;FARPTR   dummyfp;int   err;	/* returns a real mode pointer given a prot mode pointer p *///	FP_SET(dummyfp,p,data_selector);	dummyfp = p;	err = _dx_toreal(dummyfp, 0, &dummyrp);	if (err) {	   printf("Fatal Error _dx_toreal (0x%lX)\n", (ULONG) p);	   exit(err);	}	return(dummyrp);	} /* PROT_TO_REAL */FARPTR REAL_TO_PROT(REALPTR rp)  /* converts a REALPTR to a FARPTR */{FARPTR	dummyfp;	FP_SET(dummyfp,LINEARIZE(rp),SS_DOSMEM);	return (dummyfp); } /* REAL_TO_PROT */FARPTR NEARPTR_TO_FARPTR(void *ptr)/* Convert a near (32 bit linear) pointer to a far (48 bit) pointer. */{	FARPTR dummyfptr;	FP_SET(dummyfptr, ptr, data_selector);	return(dummyfptr);} /* NEARPTR_TO_FARPTR() */long BufferSizeCheck(FARPTR ptr, char *function_name, int print_message)/* Check passed ptr to make sure that it points to a valid location in * the real-mode parameter passing buffer.  If not, just report an * error for now. */{	if ((long)ptr < (long)rm_address) {		printf("Invalid address for real mode parameters in function: %s\n",function_name);		exit(1);	}	if ((long)ptr > (long)rm_end_address) {		if (print_message) {			printf("Parameters too large for passing to real mode in function: %s\n",function_name);			printf("Value of ptr - rm_end_address:%ld\n",(long)(ptr - (FARPTR)rm_end_address));		}		return (long)((long)ptr - (long)rm_end_address);	}	return 0;	/* passed the size check */} /* BufferSizeCheck() */void CheckRealError(int Err, char *func_name) {	if (Err) {		printf("DOS386 real mode call error: %s\n",func_name);		exit(1);	} /* if */} /* CheckRealError() */UDIError CAT(UDIPConnect,UDI12FUNCVER)(			REALPTR UDIConnectAddr, 			char *Configuration,		/* In  */			UDISessionId *Session,		/* Out */			DOSTerm _far *TermStruct)	/* In  */{	int			err;	UDISessionId _far	*SessionPtr;	UDIError 		ConnectErr;	USHORT			rm_seg,rm_size;	_Packed struct {		REALPTR		Configuration;		REALPTR  	Session;		REALPTR		TermStruct;	} params;	if (!buffer_allocated) {		/* Need to get address of conventional memory area for passing parameters.		 * This will set it for future use everywhere, not just in this function. 		 * rm_address is the protected (32 bit) pointer to the real mode parameter.		 * passing area.  rm_buffer_addr is the real mode pointer to the same buffer.		 */		err = _dx_real_alloc(REAL_BUFFER_SIZE,&rm_seg,&rm_size);		if (err) {			printf("Unable to allocate real-mode parameter transfer area (_dx_real_alloc)\n");			exit(0);		}		/* rm_seg is the real mode paragraph (segment).		 * Build rm_buffer_addr to be the full real mode pointer (seg:ofst)		 */		RP_SET(rm_buffer_addr, 0, rm_seg);		/*		 * rm_address will be the protected pointer to that same buffer		 */		rm_address       = (USHORT _far *)REAL_TO_PROT(rm_buffer_addr);		rm_end_address   = (USHORT _far *) (((char _far *)rm_address) + REAL_BUFFER_SIZE*16);		buffer_allocated = 1;	}			/* Get pointers to locations where passed by reference parameters 	 * will be stored in the parameter passing buffer area.  The first	 * parameter is always at rm_buffer (= rm_buffer_addr in real mode).	 */	/* NOTE: see comments under UDIPDisconnect for explanation of why	 * we don't copy TermStruct even though it's an in parameter.	 */	SessionPtr = (UDISessionId _far *)((char _far *)rm_address + strlen(Configuration)+1);				       	if (BufferSizeCheck((FARPTR)(SessionPtr + sizeof(UDISessionId)),"UDIPConnect" UDI12FUNCVERSTR,PRINT_ON)) {		return UDIErrorIPCInternal;	} /* if */	/* Move input parameters which are passed by reference into paramter buffer area. */	_fmemmove(rm_address,NEARPTR_TO_FARPTR(Configuration),strlen(Configuration)+1);	_fmemmove(SessionPtr,NEARPTR_TO_FARPTR(Session),sizeof(UDISessionId));	/* Put actual parameters into packed structure for passing to real	 * mode function.	 */	params.Configuration = rm_buffer_addr;	params.Session       = PROT_TO_REAL((FARPTR) SessionPtr);	params.TermStruct    = PROT_TO_REAL((FARPTR)TermStruct);	/* Call the real-mode function with the address of the function,	 * the number of bytes in the packed structure and the address of	 * the structure.	 */	ConnectErr = REALCALL(UDIConnectAddr,params);	CheckRealError(ConnectErr,"UDIConnect" UDI12FUNCVERSTR);	/* Copy output parameters from parameter passing area back to protected space	 */	_fmemmove(NEARPTR_TO_FARPTR(Session),SessionPtr,sizeof(UDISessionId));	return FUNC_VAL;} /* UDIPConnect (UDI 1.2) */#ifdef UDI13/* 4/93 MDT - This function is needed only for UDI 1.3 and greater  *            implementations.  This code should be checked when the *            final specification for UDI 1.3 becomes available. */UDIError UDIPConnect_13(	REALPTR 	UDIConnectAddr, 	char		*Configuration, 	/* In  */	UDISessionId	*Session, 		/* Out */	DOSTerm 	*TermStruct,		/* In  */	UDIUInt32	DFEIPCId,		/* In  1.3 */	UDIUInt32	*TIPIPCId,		/* Out 1.3 */	struct UDIDFEVecRec *DFEVecRec		/* In  1.3 */	){	int			err;	UDISessionId _far	*SessionPtr;	UDIUInt32 _far		*TIPIPCIdPtr;	UDIError 		ConnectErr;	USHORT			rm_seg,rm_size;	_Packed struct {		REALPTR		Configuration;		REALPTR  	Session;		REALPTR		TermStruct;		UDIUInt32	DFEIPCId;		REALPTR		TIPIPCId;		REALPTR		DFEVecRec;	} params;		if (!buffer_allocated) {		/* Need to get address of conventional memory area for passing parameters.		 * This will set it for future use everywhere, not just in this function. 		 * rm_address is the protected (32 bit) pointer to the real mode parameter.		 * passing area.  rm_buffer_addr is the real mode pointer to the same buffer.		 */		err = _dx_real_alloc(REAL_BUFFER_SIZE,&rm_seg,&rm_size);		if (err) {			printf("Unable to allocate real-mode parameter transfer area (_dx_real_alloc)\n");			exit(0);		}		/* rm_seg is the real mode paragraph (segment).		 * Build rm_buffer_addr to be the full real mode pointer (seg:ofst)		 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -