v86 icon indicating copy to clipboard operation
v86 copied to clipboard

Windows 2000: serial port not working

Open stasoid opened this issue 3 years ago • 2 comments

How to reproduce:

  • open Windows 2000 VM
  • run cmd.exe (Start > Run > cmd)
  • run this command: type com1

I get this error: The system cannot find the file specified. This shouldn't be happening if COM1 is available.

stasoid avatar May 14 '22 14:05 stasoid

I studied COM port detection in Windows 2000 SP4 on v86 and did not find any anomalies. Both seabios and ntdetect.com correctly find COM1 port.

I changed uart.js to log every IO operation on serial ports and set LOG_LEVEL = LOG_SERIAL in config.js. Modified uart.js and raw log are in the attachment.

Below is annotated log. This is the full log, there is no other COM port activity beyond SeaBIOS:serial_setup and ntdetect.com:GetComportInformation.

SeaBIOS: serial_setup > detect_serial

0x3F8+1: write 0x2      outb(0x02, port+SEROFF_IER);
0x3F8+1: read 0x2       u8 ier = inb(port+SEROFF_IER);  // GOOD
0x3F8+2: read 0xC2      u8 iir = inb(port+SEROFF_IIR);  // GOOD   (0xC2 & 0x3F) == 0x02
0x3F8+1: write 0x0      outb(0x00, port+SEROFF_IER);

ntdetect.com: GetComportInformation

// GetComportInformation > DoesPortExist
0x3F8+3: read 0x0       LineControl_Save = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER);
0x3F8+3: write 0x80     WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl | SERIAL_LCR_DLAB) );
0x3F8+1: read 0x0       BaudRateMsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB);
0x3F8: read 0x0         BaudRateLsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB);
0x3F8+1: write 0x0      WRITE_PORT_UCHAR(Address+DIVISOR_LATCH_MSB, BAUD_RATE_9600_MSB);
0x3F8: write 0xC        WRITE_PORT_UCHAR(Address+DIVISOR_LATCH_LSB, BAUD_RATE_9600_LSB);
0x3F8+3: write 0x0      WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl & ~SERIAL_LCR_DLAB) );
0x3F8+1: read 0x0       IerContents = READ_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER);
0x3F8+1: write 0xF      WRITE_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER, IER_TEST_VALUE);
0x3F8+3: write 0x80     WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl | SERIAL_LCR_DLAB) ); // Read baud rate divisor.  The values we read should be equal to the values we set earlier.
0x3F8+1: read 0x0       Temp = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB); // GOOD
0x3F8: read 0xC         Temp = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB); // GOOD

0x3F8+3: write 0x0      WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl & ~SERIAL_LCR_DLAB) ); // Read IER and it should be equal to the value we set earlier.
0x3F8+1: read 0xF       Temp = READ_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER);  // GOOD

// cleanup
0x3F8+3: write 0x0
0x3F8+1: write 0x0
0x3F8+3: write 0x80
0x3F8+1: write 0x0
0x3F8: write 0x0
0x3F8+3: write 0x0

// end of DoesPortExist

GetComportInformation > HwInterruptDetection > SerialInterruptDismiss   // (*InterruptDismissRoutine)(BasePort);  // line 380
0x3F8+2: read 0xC1
0x3F8+1: write 0x0

GetComportInformation > HwInterruptDetection > SerialInterruptRequest   // (*InterruptRequestRoutine)(BasePort);  // line 404
0x3F8+4: write 0x8
0x3F8+1: write 0x0
0x3F8+1: write 0xF

// (*InterruptDismissRoutine)(BasePort);  // line 474
0x3F8+2: read 0xC1  
0x3F8+1: write 0x0

// (*InterruptRequestRoutine)(BasePort);  // line 498
0x3F8+4: write 0x8
0x3F8+1: write 0x0
0x3F8+1: write 0xF

// (*InterruptDismissRoutine)(BasePort);  // line 561
0x3F8+2: read 0xC1
0x3F8+1: write 0x0

// cleanup
0x3F8+1: write 0x0      // line 813
0x3F8+4: write 0x0      // line 814

// end of GetComportInformation

stasoid avatar May 16 '22 21:05 stasoid

Probably related to #610. A PR would welcome.

copy avatar May 17 '22 19:05 copy