21. marts 2001 - 09:15
#3
Hvis du mener, at du vil give mig 15-20 point, kan du enten oprettet et nyt spg, eller under pointgivningen tage avanceret/udvidet (kan ikke lige huske hvad knappen hedder).
Jeg kender ikke lige til steder, hvor der er noget med direkte tilgang til et netkort. Det kan jeg vist ikke hjælpe dig med :(
21. marts 2001 - 10:14
#4
Hvis du skal have fat i det aktuelle I/O område for et PnP kort, findes der nogle bios interrupt kald der kan returnere dem til dig - forudsat at du kender kortets ID.
Jeg har følgende lidt lange eksempel på hvordan man finder den for et PCI I/O kort fra Arcom. Det er FIND_PCIDEVICE funktionen der er interessant for dig.
/* ************************************************************************ *
* apci.c - PCI Access Demo program *
* *
* $Author DGS$ *
* $Log$ *
* *
* Modification History *
* 1-03-98 DGS 1 *
* - Created using BorlandC 4.5. *
* ************************************************************************ */
/******************************* Include Files ******************************/
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
/**************************** General Definitions ***************************/
#define FALSE 0
#define TRUE (!FALSE) /* TRUE equals not FALSE */
#define PCI 0x1A /* PCI Interrupt */
#define PLX 0x10B5 /* PLX Technology vendor ID */
#define PCI9050 0x9050 /* PCI9050 ID */
#define BASEADDRREG 0x18 /* Base Address register */
#define SUBVENDOR 0x2C /* Subsystem Vendor ID */
#define SUBID 0x2E /* Subsystem ID */
#define INTLINE 0x3C /* Interrupt Line assigneded */
#define INTPIN 0x3D /* PCI Interrupt Pin */
#define ARCOM 0x13AB /* ARCOM\'s Vendor ID */
#define USERLED 0x80 /* User LED Index register */
#define LEDON 0x01 /* LED ON */
#define LEDOFF 0x00 /* LED OFF */
/**************************** Board Definitions ******************************/
#define IB40 0x591 /* APCI-IB40 */
#define SER4 0x592 /* APCI-SER4 */
#define RELAY8 0x594 /* APCI-RELAY8/IN8 */
#define ADADIO 0x605 /* APCI-ADADIO */
/****************************** Global Variables ****************************/
int NOBOARD = TRUE; /* ARCOM PCI not found*/
int ERROR = FALSE; /* Global Error Flag */
union REGS inregs, outregs;
/* Definitions so that BYTE is 8-bits, WORD is 16-bits, and DWORD is 32-bits */
typedef unsigned char BYTE ;
typedef unsigned short WORD ;
typedef unsigned long DWORD ;
/****************************** Function Prototypes *************************/
void main (void);
WORD FIND_PCI_DEVICE(WORD device, WORD vendor, WORD index);
WORD READ_CONFIG_WORD(WORD PCIdevice, BYTE Regnum);
WORD READ_CONFIG_BYTE(WORD PCIdevice, BYTE Regnum);
void WRITE_CONFIG_WORD(WORD PCIdevice, BYTE Regnum, WORD Value);
void Verifyboard(WORD board);
WORD IOaddrange(WORD PCIdevice);
void Testboard(WORD base, WORD board);
void IoWrite(int base, int ioaddr, int value);
/******************************** Main Program ******************************/
void main(void)
{
int c;
int Index = 0; /* Instance of device */
WORD PCIdevice; /* Bus number, Device nuber and Function number */
WORD board; /* APCI board ID */
WORD regval; /* Register Value */
WORD base; /* Base address */
clrscr();
printf(\"Arcom PCI board detection utility Version 1.0\\n\\n\"); /* Signon message */
while(ERROR==FALSE)
{
PCIdevice = (FIND_PCI_DEVICE(PCI9050, PLX, Index)); /* Find PCI device */
if (ERROR == TRUE)
break;
NOBOARD=FALSE; /* At least 1 board with PLX device detected */
regval = (READ_CONFIG_WORD(PCIdevice, SUBVENDOR)); /* Read Subvendor ID */
if (ERROR == TRUE)
break;
if (regval == ARCOM) /* Check Vendor is Arcom */
{
board = READ_CONFIG_WORD(PCIdevice, SUBID); /* Read Subsystem ID */
Verifyboard(board); /* Check board and display meaasge */
base = IOaddrange(PCIdevice); /* Check address range */
regval=READ_CONFIG_BYTE(PCIdevice, INTPIN); /* Detect if device has IRQ */
if (regval != 0)
{
regval=READ_CONFIG_BYTE(PCIdevice, INTLINE); /* Detect IRQ routing */
printf(\"\\tInterrupt\\tIRQ%d\\n\",regval);
}
printf(\"\\nTest Board access Y/N ?\"); /* Ask if user wants to test board */
c=getch();
if ((c=toupper(c))==\'Y\')
{
Testboard(base,board); /* Flash board LED */
}
else
{
printf(\"\\n\\n\"); /* Format display correctly */
}
}
++Index; /* Increase index and search for next device */
}
if (NOBOARD==TRUE)
printf(\"No Arcom PCI boards detected\\n\");
}
/*****************************************************************************
* Find_pci_device - Uses INT 1A to find a specified PCI device *
* *
* parameters passed : Device - PCI chip *
* Vendor - Manufacturers ID *
* Index - Instance of device *
* Return values : PCIdevice - bus, device and function number *
****************************************************************************/
WORD FIND_PCI_DEVICE(WORD device, WORD vendor, WORD index)
{
WORD PCIdevice = 0;
inregs.h.ah = 0xb1; /* PCI function ID */
inregs.h.al = 0x02; /* FIND_PCI_DEVICE Function */
inregs.x.cx = device; /* Device ID */
inregs.x.dx = vendor; /* Vendor ID */
inregs.x.si = index; /* Instance of device */
int86(PCI, &inregs, &outregs); /* PCI Interrupt call */
if((outregs.h.ah) == 0x86)
ERROR = TRUE;
else
PCIdevice = outregs.x.bx;
return (PCIdevice);
}
/*****************************************************************************
* Read_Config_Word - Uses INT 1A to read a specified word *
* *
* parameters passed : PCIdevice - bus, device and function number *
* Regnum - register to read *
* Return values : Regval - Value returned from register *
****************************************************************************/
WORD READ_CONFIG_WORD(WORD PCIdevice, BYTE Regnum)
{
WORD Regval;
inregs.h.ah = 0xb1; /* PCI function ID */
inregs.h.al = 0x09; /* READ_CONFIG_WORD Function */
inregs.x.bx = PCIdevice; /* Device */
inregs.x.di = Regnum; /* Register number to read */
int86(PCI, &inregs, &outregs); /* PCI Interrupt call */
if (outregs.h.ah == 0x87)
{
printf(\"Error = BAD_REGISTER_NUMBER\\n\");
ERROR = TRUE;
}
else
Regval = outregs.x.cx;
return (Regval);
}
/*****************************************************************************
* Read_Config_Byte - Uses INT 1A to read a specified byte *
* *
* parameters passed : Regnum - Register to write *
* Value - Value to be written *
* Return values : Regval - value read *
****************************************************************************/
WORD READ_CONFIG_BYTE(WORD PCIdevice, BYTE Regnum)
{
BYTE Regval;
inregs.h.ah = 0xb1; /* PCI function ID */
inregs.h.al = 0x08; /* READ_CONFIG_WORD Function */
inregs.x.bx = PCIdevice; /* Device */
inregs.x.di = Regnum; /* Register number to read */
int86(PCI, &inregs, &outregs); /* PCI Interrupt call */
if (outregs.h.ah == 0x87)
{
printf(\"Error = BAD_REGISTER_NUMBER\\n\");
ERROR = TRUE;
}
else
Regval = outregs.h.cl;
return (Regval);
}
/*****************************************************************************
* Write_Config_Word - Uses INT 1A to wrie a specified word *
* *
* parameters passed : PCIdevice - Bus, device and function number *
* Regnum - Register to write *
* Value - Value to be written *
* Return values : None *
****************************************************************************/
void WRITE_CONFIG_WORD(WORD PCIdevice, BYTE Regnum, WORD Value)
{
inregs.h.ah = 0xb1; /* PCI function ID */
inregs.h.al = 0x0c; /* WRITE_CONFIG_WORD Function */
inregs.x.bx = PCIdevice; /* Device */
inregs.x.di = Regnum; /* Register number to write */
inregs.x.cx = Value;
int86(PCI, &inregs, &outregs); /* PCI Interrupt call */
if (outregs.h.ah == 0x87)
{
printf(\"Error = BAD_REGISTER_NUMBER\\n\");
ERROR = TRUE;
}
}
/*****************************************************************************
* Verifyboard - Checks which board has been found and prints a message to *
* the display *
* parameters passed : Board - name of board found *
* Return values : None *
****************************************************************************/
void Verifyboard (WORD board)
{
printf(\"\\tPCI Board\\t\");
switch(board)
{
case IB40 :printf(\"APCI-IB40\\n\");
break;
case SER4 :printf(\"APCI-SER4\\n\");
break;
case RELAY8 :printf(\"APCI-RELAY8/IN8\\n\");
break;
case ADADIO :printf(\"APCI-ADADIO\\n\");
break;
default :printf(\"UNKNOWN\\n\");
break;
}
}
/*****************************************************************************
* IOaddrange - Determines I/O address range allocated to PCI card *
* *
* parameters passed : PCIdevice - Bus, device and Function number *
* Return values : lower - Base address *
****************************************************************************/
WORD IOaddrange(WORD PCIdevice)
{
WORD lower, upper;
lower = READ_CONFIG_WORD(PCIdevice, BASEADDRREG); /* Read Base addr register */
WRITE_CONFIG_WORD(PCIdevice, BASEADDRREG,0xFFFF); /* Write all 1\'s to base addr register */
upper = READ_CONFIG_WORD(PCIdevice, BASEADDRREG); /* Read base addr register */
WRITE_CONFIG_WORD(PCIdevice, BASEADDRREG, lower); /* Restore orignal value */
--lower; /* Strip off I/O bit */
--upper;
upper = ~upper; /* Invert upper */
upper = upper + lower; /* Add to base addr to give range */
printf(\"\\tAddrees Range\\t%xH - %xH\\n\",lower,upper);
return(lower); /* Return base address */
}
/*****************************************************************************
* Testboard - Flashes user led until key is pressed *
* *
* parameters passed : Base - base address of board *
* Board - board name *
* Return values : None *
****************************************************************************/
void Testboard(WORD base, WORD board)
{
if (board == RELAY8)
{
printf(\"\\n\\nThe RED ACCESS LED should be ON, press any key to turm OFF\\n\\n\");
while(!kbhit())
{
IoWrite(base,0,0);
}
getch();
}
else
{
printf(\"\\n\\nThe GREEN user LED shoud be flashing, press any Key to continue.\\n\\n\");
while (!kbhit())
{
IoWrite(base,USERLED, LEDON); /* Turn User LED ON */
delay(500); /* Wait 500ms */
IoWrite(base,USERLED, LEDOFF); /* Turn user LED OFF */
delay(500); /* Wait 500ms */
}
getch();
}
}
/***************************************************************************
* IoWrite - write to the port. *
* *
* Paramters passed : BASE - base address of board under test. *
* ioaddr - address pointer to the port. *
* value - data to be output. *
* Return : None. *
****************************************************************************/
void IoWrite(int base, int ioaddr, int value)
{
outp(base,ioaddr); /* Set up I/O address */
outp(base+1,value); /* Write value to I/O address */
}