端口操作代码
//读端口数据
UCHAR In_8(PUCHAR Port)
{
UCHAR Value;
__asm{
mov edx,Port
mov eax,0
in al,dx
mov Value,al
nop
nop
}
return Value;
}
USHORT In_16(PUSHORT Port)
{
USHORT Value;
__asm{
mov edx, Port
mov eax, 0
in ax, dx
mov Value, ax
nop
nop
}
return Value;
}
ULONG In_32(PULONG Port)
{
ULONG Value;
__asm{
mov edx, Port
mov eax, 0
in eax, dx
mov Value, eax
nop
nop
}
return Value;
}
//往端口写数据
void Out_8(PUCHAR Port,UCHAR Value)
{
__asm{
mov edx,Port
mov al,Value
out dx,al
nop
nop
}
}
void Out_16(PUSHORT Port, USHORT Value)
{
__asm{
mov edx, Port
mov ax, Value
out dx, ax
nop
nop
}
}
void Out_32(PULONG Port, ULONG Value)
{
__asm{
mov edx, Port
mov eax, Value
out dx, eax
nop
nop
}
}
对此微软提供了对应了API
READ_PORT_UCHAR()
READ_PORT_USHORT()
READ_PORT_ULONG()
WRITE_PORT_UCHAR()
WRITE_PORT_USHORT()
WRITE_PORT_ULONG()
让PC喇叭发声
喇叭端口的低两位是控制开关
0x43端口 :
第0位:计数方式
0 : 代表二进制
1 : BCD 如果该8位的值是0x78h 那么值就是78
第 1 2 3位 代表时钟运行方式
第4 5位
0 0 代表寄存器已经锁存
0 1 读写8位
1 0 读写高8位
1 1 先读低8位 然后读高8位
第6 7 位的值代表选择的是哪一个计数器
0 0 代表0号计数器
0 1 代表1号计数器
1 0 代表2号计数器
在这里插入代码片
//f为输入的频率
VOID SoundOff()
{
//读出0x61端口的值
UCHAR Temp = READ_PORT_UCHAR((PUCHAR)0x61);
Temp &= 0xfc; //低两位置1 关闭喇叭开关
WRITE_PORT_UCHAR((PUCHAR)0x61, Temp);
}
// 频率 2000
VOID Sound(ULONG f)
{
USHORT b = 1193180 / f;
//读出0x61端口的值
UCHAR Temp=READ_PORT_UCHAR((PUCHAR)0x61);
Temp |= 3; //低两位置1 打开喇叭开关
WRITE_PORT_UCHAR((PUCHAR)0x61,Temp);
//配置时钟
WRITE_PORT_UCHAR((PUCHAR)0x43,0xb6);
//写入计数器
WRITE_PORT_UCHAR((PUCHAR)0x42,b&0xff);
WRITE_PORT_UCHAR((PUCHAR)0x42, (b>>8)&0xff);
}