如何在MS-DOS x86 汇编语言中检测16550 UART 芯片?
How to detect 16550 UART chip in MS-DOS x86 Assembly Language?
我正在研究如何在 MS-DOS 程序集中编写代码来检测是否安装了 16550 UART 芯片(串行控制器),或者是否有通用方法来检测所安装的 UART 芯片的型号.
到目前为止,我已经检查了以下资源:
- 高级MS-DOS编程第二版
- 写入MS-DOS设备
司机
- Ralf Brown 的中断列表(虽然它可能在这里,但我已经尝试在其中搜索 serial 和 16550 但没有找到)
- 已在 DosBox 源代码中搜索线索,因为我知道它已经实现了这一点,但找不到位置
- https://wiki.osdev.org/Serial_Ports
尚未找到 MS-DOS 的 16550 编程手册副本。
我初始化串口没有问题,sending/receiving 数据给它,挑战是如何检测特定芯片或至少确认芯片是否为 16550 型号。
虽然不在汇编程序中,但可以将其转换为汇编程序。在 C 中来自 http://www.sci.muni.cz/docs/pc/serport.txt
int detect_UART(unsigned baseaddr)
{
// this function returns 0 if no UART is installed.
// 1: 8250, 2: 16450 or 8250 with scratch reg., 3: 16550, 4: 16550A
int x,olddata;
// check if a UART is present anyway
olddata=inp(baseaddr+4);
outp(baseaddr+4,0x10);
if ((inp(baseaddr+6)&0xf0)) return 0;
outp(baseaddr+4,0x1f);
if ((inp(baseaddr+6)&0xf0)!=0xf0) return 0;
outp(baseaddr+4,olddata);
// next thing to do is look for the scratch register
olddata=inp(baseaddr+7);
outp(baseaddr+7,0x55);
if (inp(baseaddr+7)!=0x55) return 1;
outp(baseaddr+7,0xAA);
if (inp(baseaddr+7)!=0xAA) return 1;
outp(baseaddr+7,olddata); // we don't need to restore it if it's not there
// then check if there's a FIFO
outp(baseaddr+2,1);
x=inp(baseaddr+2);
// some old-fashioned software relies on this!
outp(baseaddr+2,0x0);
if ((x&0x80)==0) return 2;
if ((x&0x40)==0) return 3;
return 4;
}
我正在研究如何在 MS-DOS 程序集中编写代码来检测是否安装了 16550 UART 芯片(串行控制器),或者是否有通用方法来检测所安装的 UART 芯片的型号.
到目前为止,我已经检查了以下资源:
- 高级MS-DOS编程第二版
- 写入MS-DOS设备 司机
- Ralf Brown 的中断列表(虽然它可能在这里,但我已经尝试在其中搜索 serial 和 16550 但没有找到)
- 已在 DosBox 源代码中搜索线索,因为我知道它已经实现了这一点,但找不到位置
- https://wiki.osdev.org/Serial_Ports
尚未找到 MS-DOS 的 16550 编程手册副本。 我初始化串口没有问题,sending/receiving 数据给它,挑战是如何检测特定芯片或至少确认芯片是否为 16550 型号。
虽然不在汇编程序中,但可以将其转换为汇编程序。在 C 中来自 http://www.sci.muni.cz/docs/pc/serport.txt
int detect_UART(unsigned baseaddr)
{
// this function returns 0 if no UART is installed.
// 1: 8250, 2: 16450 or 8250 with scratch reg., 3: 16550, 4: 16550A
int x,olddata;
// check if a UART is present anyway
olddata=inp(baseaddr+4);
outp(baseaddr+4,0x10);
if ((inp(baseaddr+6)&0xf0)) return 0;
outp(baseaddr+4,0x1f);
if ((inp(baseaddr+6)&0xf0)!=0xf0) return 0;
outp(baseaddr+4,olddata);
// next thing to do is look for the scratch register
olddata=inp(baseaddr+7);
outp(baseaddr+7,0x55);
if (inp(baseaddr+7)!=0x55) return 1;
outp(baseaddr+7,0xAA);
if (inp(baseaddr+7)!=0xAA) return 1;
outp(baseaddr+7,olddata); // we don't need to restore it if it's not there
// then check if there's a FIFO
outp(baseaddr+2,1);
x=inp(baseaddr+2);
// some old-fashioned software relies on this!
outp(baseaddr+2,0x0);
if ((x&0x80)==0) return 2;
if ((x&0x40)==0) return 3;
return 4;
}