Windows 95 VxD C Source Code for VANYDEVD

 

Listing 3

/// VANYDEVDc.c

// --------------------------------------------
// Dynamically loadable VxD for ANYDEV board
// --------------------------------------------
#define WIN32_LEAN_AND_MEAN // Excludes un-needed parts of windows.h
#include "windows.h"
#include <e:/ddk95/inc32/vmm.h>
#include <e:/ddk95/inc32/vwin32.h>
#include <e:/ddk95/inc32/debug.h>
#include "VANYDEVD.H"


// -------------------------------------
// Externs defined in assembly module 
// -------------------------------------
// These defined in assembly for the VMM.INC or VPICD.INC file inclusion
extern DWORD GET_BD_MEM(void);
extern DWORD Virt_IRQ(void);
extern DWORD Get_IRQ_Status(void);
extern void UNVirt_IRQ(DWORD IRQhandle);
extern void End_ISR(DWORD IRQhandle);
extern void Physically_Mask_IRQ(DWORD IRQhandle);
extern void Physically_UNMask_IRQ(DWORD IRQhandle);


// ------------------------
// PRAGMA for this DATA 
// ------------------------
// Establish segment
#pragma data_seg ( "_LDATA","_LCODE")


// ------------------------------------
// Data structures MUST be INITIALIZED
// ------------------------------------
ADEV ANYDEVX = {0}; // Main structure for ANYDEV -- shared by app 


// ------------------------
// PRAGMAS for this CODE 
// ------------------------
// Establish segment
#pragma code_seg ( "_LTEXT", "_LCODE" )
//No stack checking for routines in this module
#pragma check_stack(off)


// ----------------
// Disable hardware
// ----------------
void Disable_AnyDev(void)
{
	//This would likely be a port WRITE to DISABLE the board's interrupt	 		
}


// ----------------
// Enable hardware
// ----------------
void Enable_AnyDev(void)
{
	//This would likely be a port WRITE to ENABLE the board's interrupt	 		
}
// --------------------------
// ISR Processing for ANYDEV
// --------------------------
void Process_ISR(void)
{
	//This is where the user might SET FLAGS and indicators in the ANYDEVX structure
	//in order to notify the application that data is available below 1MB	 		
}


// -----------------
// ISR for ANYDEV
// -----------------
void _declspec(naked)ISR_ANYDEV(void)
{
	// Save registers
	_asm sti
	_asm pushad
	_asm pushfd


	//Process the ISR 
	Process_ISR();


	//End ISR
	_asm clc
	End_ISR(ANYDEVX.IRQhandle);


	//Set GOOD return code
	_asm clc


	//Restore saved registers
	_asm popfd
	_asm popad
	_asm ret;
}


// -------------------
// Virtualize the IRQ
// -------------------
DWORD CVirt_IRQ(void)
{
	// If in use by an instance of this program, RETURN with BAD code
	if (ANYDEVX.IRQcount)
		return (BOGUSADDRESS);


	// If in use by another program, RETURN with BAD code
	ANYDEVX.IRQstatus = Get_IRQ_Status();
	if (ANYDEVX.IRQstatus)
		return (BOGUSADDRESS);


	// If IRQ NOT in use this point is reached
	// Set BAD return code
	ANYDEVX.IRQhandle = BOGUSADDRESS;
	// Disable ANYDEV hardware	
	Disable_AnyDev();
	// Get global memory address below 1mb
	ANYDEVX.Global_addr_1MB = GET_BD_MEM();
	if (ANYDEVX.Global_addr_1MB != BOGUSADDRESS)
		{
		// Virtualize the IRQ
		ANYDEVX.IRQhandle = Virt_IRQ();	
		if (ANYDEVX.IRQhandle != BOGUSADDRESS)
			{
			// unmask the IRQ, set OK flag & increment IRQ count
	 		Physically_UNMask_IRQ(ANYDEVX.IRQhandle);
	 		ANYDEVX.IRQflags |= IRQ_VIRT_OK;
			++(ANYDEVX.IRQcount);
			}
		}
	return(ANYDEVX.IRQhandle);
}
// ----------------------
// UN Virtualize the IRQ
// ----------------------
void CUNVirt_IRQ(DWORD IRQhandle)
{
 // if IRQ has been successfully virtualized
 if ((ANYDEVX.IRQhandle != 0)
 &&  (ANYDEVX.IRQhandle != BOGUSADDRESS))
 	{
	// Physically mask the IRQ and UN virtualized it
	Physically_Mask_IRQ(ANYDEVX.IRQhandle);
	UNVirt_IRQ(ANYDEVX.IRQhandle);
	}
// Set UNvirtualized flags and indicators
ANYDEVX.IRQhandle = BOGUSADDRESS;
ANYDEVX.IRQflags &= ~IRQ_VIRT_OK;
	return;
}


// ---------------------------------------
// Set Good Return code for DIOC requests
// ---------------------------------------
void _declspec(naked)GoodReturnDIOC(void)
{
	// Clear eax and carry flag for GOOD return
	_asm xor eax,eax
	_asm clc
	_asm ret;
}


// ---------------------------------------
// Set Bad Return code for DIOC requests
// ---------------------------------------
void _declspec(naked) BadReturnDIOC(void)
{
	// NOTE: 50 is a FCN NOT SUPPORTED code -- ok to use
	// SET carry flag for BAD return
	_asm mov eax,50
	_asm stc
	_asm ret;
}




// ------------------------------
// Routine for ANYDEV Device UNINIT  
// ------------------------------
void CVANYDEVD_Device_UNInit()
{
// Disable ANYDEV, Unvirtualize IRQ, set GOOD return code
	Disable_AnyDev();			
	CUNVirt_IRQ(ANYDEVX.IRQhandle);	
	GoodReturnDIOC();			
	return;
}
// ------------------------------
// Routine for ANYDEV Device INIT  
// ------------------------------


void CVANYDEVD_Device_Init()
{
DWORD retcode;


	// Try to virtualize the IRQ
	retcode = CVirt_IRQ();
	// Set GOOD or BAD return code based on success
	if (retcode == BOGUSADDRESS)
		BadReturnDIOC();
	else
	    GoodReturnDIOC();
	return;
}
// --------------------------------
// Routine for ANYDEV Device IO ctrl  
// --------------------------------
void CVANYDEVD_Device_IOctrl(PDIOCPARAMETERS ptr)
{
DWORD *obuf1;
	// Field the DEV IO requests from VMM
	switch(ptr->dwIoControlCode)
		{
		case(VANYDEVD_INIT_ADEV_HARDWARE):
			ANYDEVX.flags = 0;
			//User likely to require other initialization here
		break;
		case(VANYDEVD_GRAB_ADDRESSES):
			// Point to Output buffer
			obuf1 = (DWORD *) ptr->lpvOutBuffer;
			// Return GLOBAL 1MB addr, addr of data structure
			// and return indicators of IRQ virtuaization request
			*obuf1 = ANYDEVX.Global_addr_1MB;
		  	*(obuf1+1) = (DWORD) &ANYDEVX;
			*(obuf1+2) = (DWORD) ANYDEVX.IRQhandle;
			*(obuf1+3) = (DWORD) ANYDEVX.IRQflags;
			//User might want to return other/different values here
		break;
		case(VANYDEVD_ENABLE_ANYDEV_HDWR):
			//Call routine to enable interrupt
			Enable_AnyDev();
		break;
		case(VANYDEVD_DISABLE_ANYDEV_HWR):
			//Call routine to disable interrupt
			Disable_AnyDev();
		break;
		//The below DIOC_GETVERSION is a part of the dynamic load protocol
		//It MUST return a GOOD code (all codes here use GoodReturnDIOC()
		case(DIOC_GETVERSION):
		case(DIOC_CLOSEHANDLE):
		default:
		break;
		}
 	GoodReturnDIOC();
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值