assembly 如何在MS-DOS x86汇编语言中检测16550 UART芯片?

gg0vcinb  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(157)

我正在尝试如何在MS-DOS汇编中编写代码来检测是否安装了16550 UART芯片(串行控制器),或者是否有一种通用的方法来检测所安装的UART芯片的型号。
到目前为止,我已经检查了以下资源:

  • 高级MS-DOS程序设计第二版
  • 编写MS-DOS设备驱动程序
  • Ralf Brown的中断列表(虽然它可能在这里,但我已经尝试搜索串行和16550,但没有找到它)
  • 我已经搜索了DosBox的源代码来寻找线索,因为我知道它已经实现了这一点,但找不到它的位置
  • https://wiki.osdev.org/Serial_Ports

一直无法找到一份16550编程手册的MS-DOS。我没有问题初始化串行端口,发送/接收数据到它,挑战是如何检测特定的芯片或至少确认芯片是否是16550型号。

ztigrdn8

ztigrdn81#

在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;
}

相关问题