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
#include
#include
#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_sr (dword Irqhandle);
EXTERN VOID Physically_mask_irq (DWORD IRQHANDLE);
Extern void physically_unmask_irq (dword ilqhandle);
// ------------------------
// Pragma for this Data
// ------------------------
// establish segment
#pragma data_seg ("_ldata", "_ lcode")
// ------------------------------------
// Data Structures Must Be Initialized
// ------------------------------------
Adev Anydevx = {0}; // main structure for iNydev - Shared By App
// ------------------------
// prgmas 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 Likey Be a port Write to Disable The Board's Interrupt
}
// ----------------
// enable hardware
// ----------------
Void enable_Anydev (void) {
// this Would Likey 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 indeicators 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 returnof
_asm CLC
// Restore Saved Registers
_asm POPFD
_asm pop
_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);
}
// ----------------------
// unvrthualize 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 indeicators
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 Likey 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 indeicators of Irq Virtuaization Request
* obuf1 = anydevx.global_addr_1mb;
* (OBUF1 1) = (dword) & anndevx;
* (OBUF1 2) = (dword) Anydevx.irqhandle;
* (OBUF1 3) = (dword) Anydevx.irqflags;
// user mightow reeturn other / different value
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 loading protocol
// IT Must Return A Good Code (All Codes Here Use GoodReturndioc ()
Case (Dioc_getVersion):
Case (Dioc_CloseHandle):
DEFAULT:
Break;
}
GoodReturndioc ();
Return;
}