首先下载winio库,查看readme在vc++下使用,参考写了个0x70读cmos和0x61控制speaker
void io_init()
{
DWORD dwPortVal;
DWORD dwPortVal2;
DWORD dwMemVal;
char port[128];
char mem[128];
char test[128];
bool bResult;
HANDLE hPhysicalMemory;
PBYTE pbLinAddr;
// Call InitializeWinIo to initialize the WinIo library.
bResult = InitializeWinIo();
if (bResult)
{
// Under Windows NT/2000/XP, after calling InitializeWinIo,
// you can call _inp/_outp instead of using GetPortVal/SetPortVal
OnReadCmos();
OnSpeakerSound();
// Map physical addresses 0xA0000 - 0xAFFFF into the linear address space
// of the application. The value returned from the call to MapPhysToLin is
// a linear address corresponding to physical address 0xA0000. In case of
// an error, the return value is NULL.
pbLinAddr = MapPhysToLin((PBYTE)0xA0000, 65536, &hPhysicalMemory);
if (pbLinAddr)
{
// Now we can use pbLinAddr to access physical address 0xA0000
*pbLinAddr = 10;
// When you're done with pbLinAddr, call UnmapPhysicalMemory
UnmapPhysicalMemory(hPhysicalMemory, pbLinAddr);
}
// Instead of using MapPhysToLin, we can use GetPhysLong/SetPhysLong
SetPhysLong((PBYTE)0xA0000, 10);
GetPhysLong((PBYTE)0xA0000, &dwMemVal);
sprintf(mem,"%x", dwMemVal);
write_log(NORMAL_LOG,"%s|%d: %s/n",__FILE__,__LINE__,mem);
// When you're done using WinIo, call ShutdownWinIo
ShutdownWinIo();
}
else
{
printf("Error during initialization of WinIo./n");
exit(1);
}
}
// 0x70是CMOS索引端口(只写)
// 0x71是CMOS数据端口
DWORD ReadCmos(DWORD index)
{
DWORD dwPortVal;
SetPortVal(0x70,index, 4);
GetPortVal(0x71, &dwPortVal, 4);
return dwPortVal;
}
void OnReadCmos()
{
CString strInfo;
CString strTmp;
DWORD data;
strInfo = "COMS DATA:/r/n";
// 读出CMOS 128个字节
for(int i=0;i<128;i++)
{
data = ReadCmos(i);
write_log(NORMAL_LOG,"%s|%d: Byte %02X:/t%02X/r/n",__FILE__,__LINE__,i,data);
strTmp.Format("Byte %02X:/t%02X/r/n", i, data);
strInfo+=strTmp;
}
GetDlgItem(IDC_EDIT)tWindowText(strInfo);
}
void OnSpeakerSound()
{
// TODO: Add your command handler code here
// C调
// 1 = 262 Hz
Sound(262);
Sleep(500);
NoSound();
// 2 = 288 Hz
Sound(288);
Sleep(500);
NoSound();
// 3 = 320 Hz
Sound(320);
Sleep(500);
NoSound();
}
// 0x61是speaker控制端口
// 0x43是8253/8254定时器控制端口
// 0x42是8253/8254定时器通道2的端口
void CRadioDlg::Sound(DWORD freq ){
DWORD data;
if(freq>=20 && freq<=20000)
{
freq = 1193181 / freq;
GetPortVal(0x61, &data, 4);
if((data & 3) == 0)
{
SetPortVal(0x61,data | 3, 4);
SetPortVal(0x43,0xb6, 4);
}
SetPortVal(0x42,(BYTE)(freq%256), 4);
SetPortVal(0x42,(BYTE)(freq/256), 4);
}
}
void NoSound( void )
{
DWORD data;
GetPortVal(0x61, &data, 1);
SetPortVal(0x61, data & 0xfc, 1);
}