No0ne / ps2x2pico

USB keyboard/mouse to PS/2 interface converter using a Raspberry Pi Pico
MIT License
196 stars 35 forks source link

ps2x2pico initializes too slowly to be able to enter BIOS #37

Closed ssokolow closed 1 month ago

ssokolow commented 2 months ago

I just messed up the Win98SE install on my HP t5530 and, when I held F12 for "force netboot to the top of the boot order" to access my homebrew "Apple Internet Restore for DOS/Win9x PCs" so I could restore my backup, I discovered the hard way that none of those BIOS "hold X to Y" keys work, whether on a cold boot or if I warm boot via Ctrl+Alt+Del.

I'm not sure if this is fixable, but maybe there could be some kind of workaround where the ps2x2pico remembers whether a function key or Delete was being held down before a warm reboot and persists that state on the PS/2 side to the PC until USB device initialization completes and it has fresher data?

No0ne commented 2 months ago

Initialization should not take longer than 1-2 seconds as seen on the GPIO0 debug output. As soon as the keyboard mounted message appears it should work as long as the host PC doesn't prohibit PS/2 transmissions.

If theres a powercycle on the PS/2 port that you don't want/can control you can always feed the VBUS 5volts externally and not via the PS/2 ports.

ssokolow commented 2 months ago

There's only about a 1-second window when the BIOS is listening for keystrokes, if that. It's an early example of the "Don't worry about stuck key warnings. Just hold the key down while powering on to avoid missing the window." design you tend to see with UEFI.

No0ne commented 2 months ago

Ok yes, but this should only matter on cold boots and not reboots. I don't think we can get this any faster. You will need to supply power otherwise so that its on before the PC.

ssokolow commented 2 months ago

Holding F12 and then clicking to reboot from inside Windows 98 SE works to pull up my netboot environment with a genuine PS/2 keyboard but not with the ps2x2pico.

No0ne commented 2 months ago

Ok hm 🤔 that should work though. I'll build you a debug version for this problem.

bstrobel commented 2 months ago

Hi, I just came across your project and will definitely build it but I'm still waiting for the parts to arrive.

When I read the thread on this issue it immediately reminded me of a similar problem I experienced years ago when developing and building an IR remote to PS2 keyboard adapter.

Some PCs that I connected my adapter to complained about a defective keyboard (I think it might have been in the Windows event log) or stated that there is no keyboard connected although it seemed to work after disabling the keyboard presence check in these BIOSes.

I connected a cheap logic analyzer to the bus and analyzed the communication when the BIOS was booting and recorded the quite extensive communication between the PC and the keyboard. After implementing the same behavior in my implementation all PCs recognized my adapter reliably and I never had problems again. It still works to this day with a W10 PC by the way.

Do you somehow implement this boot/kb reset protocol in your implementation? If not, this might be the source of the problem.

bstrobel commented 2 months ago

I just found the recorded conversation in my notes. Maybe you can make sense of it and it helps you:

724725-724802 PS/2: Fields: Start bit

724802-725419 PS/2: Fields: Data: aa <--- PS2DEVICE_BAT_OK

725419-725496 PS/2: Fields: Parity OK

725496-725538 PS/2: Fields: Stop bit


20582078-20582155 PS/2: Fields: Start bit

20582155-20582773 PS/2: Fields: Data: ff <--- PS2HOST_CMD_RESET

20582773-20582850 PS/2: Fields: Parity OK

20582850-20582909 PS/2: Fields: Stop bit

20583304-20583381 PS/2: Fields: Start bit

20583381-20583998 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

20583998-20584075 PS/2: Fields: Parity OK

20584075-20584118 PS/2: Fields: Stop bit

20968529-20968606 PS/2: Fields: Start bit

20968606-20969225 PS/2: Fields: Data: aa <--- PS2DEVICE_BAT_OK

20969225-20969302 PS/2: Fields: Parity OK

20969302-20969344 PS/2: Fields: Stop bit

20994537-20994614 PS/2: Fields: Start bit

20994614-20995232 PS/2: Fields: Data: ed <--- PS2HOST_CMD_SET_RESET_LEDS

20995232-20995309 PS/2: Fields: Parity OK

20995309-20995369 PS/2: Fields: Stop bit

20995782-20995859 PS/2: Fields: Start bit

20995859-20996476 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

20996476-20996554 PS/2: Fields: Parity OK

20996554-20996596 PS/2: Fields: Stop bit

20997483-20997560 PS/2: Fields: Start bit

20997560-20998178 PS/2: Fields: Data: 00 <--- 0b00000000

20998178-20998255 PS/2: Fields: Parity OK

20998255-20998314 PS/2: Fields: Stop bit

20998740-20998817 PS/2: Fields: Start bit

20998817-20999434 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

20999434-20999512 PS/2: Fields: Parity OK

20999512-20999554 PS/2: Fields: Stop bit


25673423-25673500 PS/2: Fields: Start bit

25673500-25674118 PS/2: Fields: Data: f2 <--- PS2HOST_CMD_READ_ID

25674118-25674195 PS/2: Fields: Parity OK

25674195-25674254 PS/2: Fields: Stop bit

25674661-25674739 PS/2: Fields: Start bit

25674739-25675356 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25675356-25675433 PS/2: Fields: Parity OK

25675433-25675475 PS/2: Fields: Stop bit

25675590-25675668 PS/2: Fields: Start bit

25675668-25676284 PS/2: Fields: Data: ab <--- PS2DEVICE_ID_1

25676284-25676362 PS/2: Fields: Parity OK

25676362-25676404 PS/2: Fields: Stop bit

25676528-25676605 PS/2: Fields: Start bit

25676605-25677222 PS/2: Fields: Data: 83 <--- PS2DEVICE_ID_2

25677222-25677299 PS/2: Fields: Parity OK

25677299-25677341 PS/2: Fields: Stop bit

25677961-25678038 PS/2: Fields: Start bit

25678038-25678656 PS/2: Fields: Data: ed <--- PS2HOST_CMD_SET_RESET_LEDS

25678656-25678733 PS/2: Fields: Parity OK

25678733-25678792 PS/2: Fields: Stop bit

25679206-25679283 PS/2: Fields: Start bit

25679283-25679900 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25679900-25679977 PS/2: Fields: Parity OK

25679977-25680020 PS/2: Fields: Stop bit

25680906-25680983 PS/2: Fields: Start bit

25680983-25681601 PS/2: Fields: Data: 02 <--- 0b00000010

25681601-25681678 PS/2: Fields: Parity OK

25681678-25681737 PS/2: Fields: Stop bit

25682164-25682241 PS/2: Fields: Start bit

25682241-25682858 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25682858-25682936 PS/2: Fields: Parity OK

25682936-25682978 PS/2: Fields: Stop bit

25684106-25684183 PS/2: Fields: Start bit

25684183-25684801 PS/2: Fields: Data: f3 <--- PS2HOST_CMD_SET_TYPEMATIC_RATE_DELAY

25684801-25684879 PS/2: Fields: Parity OK

25684879-25684938 PS/2: Fields: Stop bit

25685352-25685429 PS/2: Fields: Start bit

25685429-25686047 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25686047-25686124 PS/2: Fields: Parity OK

25686124-25686166 PS/2: Fields: Stop bit

25687054-25687131 PS/2: Fields: Start bit

25687131-25687749 PS/2: Fields: Data: 20 <--- 0x20

25687749-25687826 PS/2: Fields: Parity OK

25687826-25687886 PS/2: Fields: Stop bit

25688305-25688382 PS/2: Fields: Start bit

25688382-25689000 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25689000-25689077 PS/2: Fields: Parity OK

25689077-25689119 PS/2: Fields: Stop bit

25690649-25690726 PS/2: Fields: Start bit

25690726-25691345 PS/2: Fields: Data: f4 <--- PS2HOST_CMD_ENABLE

25691345-25691422 PS/2: Fields: Parity OK

25691422-25691481 PS/2: Fields: Stop bit

25691896-25691973 PS/2: Fields: Start bit

25691973-25692591 PS/2: Fields: Data: fa <--- PS2DEVICE_CMD_ACK

25692591-25692668 PS/2: Fields: Parity OK

25692668-25692710 PS/2: Fields: Stop bit

No0ne commented 2 months ago

Yes, command 0xff and response 0xaa is implemented, I'll check if I can get a t5530 for debugging.

No0ne commented 2 months ago

Got one for 35 euros so I can check for my self 🥳

bstrobel commented 2 months ago

Your right. I just checked the diff and refreshed my memory. The project is 10y old and I did the fix 5y ago. How time flies... Anyway the bug was that I didn't send 0xfa (ACK) before sending the device id. I checked your code and you are doing that correctly. So no difference to what I did at the time.

Just wanted to say Thank you for this great little project. I always wanted to do something like that and never found the time. Great Work! :+1:

No0ne commented 2 months ago

Should be the same: https://github.com/No0ne/ps2x2pico/blob/486a5950fcf86650e9b1b41b5542cac5ca1523e7/src/ps2kb.c#L238 I'll check when the t5530 arrives next week.

ssokolow commented 2 months ago

Got one for 35 euros so I can check for my self 🥳

Enjoy. It makes an excellent fanless late-Win98SE-era machine if you eBay a bigger ATA disk-on-module, install the appropriate drivers off VIA's website, and either use a USB CD-ROM drive or install a period-appropriate copy of DAEMON Tools.

(The main trick is copying the install files onto the hard drive so they'll still be available when the Windows installer stops using DOS I/O drivers and loses the BIOS's USB storage device fakery.)

Heck, the only reason it's not the greatest for earlier stuff is that the onboard audio doesn't have native SoundBlaster compatibility and it doesn't have an ISA or PCI slot to stick a genuine SoundBlaster into.

It's even got VESA mounting holes so you can hang it off the back of a monitor.

No0ne commented 1 month ago

Still waiting on the t5530 order, but I haven't had time anyway at the moment.

bstrobel commented 1 month ago

@ssokolow When working on issue #38 I refactored the code a bit and streamlined the host to keyboard communication. I don't think that the Pico initializes too slowly to be honest. If you want you could try the new version I created. I have attached it here: ps2x2pico.zip

If you can it would be good if you would connect a serial terminal to the debug output and post the logs here. It would clarify what is going wrong. Each host has its own way of communicating and configuring the ps/2 keyboard. I tried and traced with a few and each one was different. Maybe yours is especially picky?

ssokolow commented 1 month ago

I'll give it a look as soon as I've made time for retro-hobby stuff again. The last week or so has been pretty busy with spring cleaning and the like.

No0ne commented 1 month ago

Finally got the t5530 and I found two potenial issues: If the key is held down before tinyusb is running it may not be detected, and (I think thats the real problem) if the host resets the keyboard (while rebooting) the repeating key is also resetted.

It works if you don't hold the key but mash it multiple times, but I think it should also work holding it down!

And yes, the bios routing of the t5530 is really fast, did not see any bios this fast before. As an alternative if you set 5sec POST delay in the bios it also works well.

I'll look into it that it works with holding the key down!

No0ne commented 1 month ago

I think I got this, its working by holding down F10 or F12 on my t5530 without POST delay and quickpost enabled. @ssokolow please try this: t5530-fix.zip

ssokolow commented 1 month ago

Will do. The last few days have been busy but I should have free time starting on Wednesday.

ssokolow commented 1 month ago

Sorry I went silent. I bruised a rib the afternoon after I said "Will do" and it took me until now to be physically able to get under my desk to access the ps2x2pico.

It and the KVM switch I plug it into are now sitting on top of the desk where I can comfortably work on them and I should be able to make time to test it either today or within the next couple of days.

ssokolow commented 1 month ago

So far, I literally haven't tested anything but the F10 and F12 keys the Ctrl+Alt+Delete key combo yet, but t5530-fix.zip does let me access the BIOS and force netboot on both a cold boot and a Ctrl+Alt+Delete warm boot by holding down the relevant key.

No0ne commented 1 month ago

Cool, thanks for testing. So is this issue fixed now?

ssokolow commented 1 month ago

Yes. As far as I can tell, t5530-fix.zip fixes it perfectly.

Thanks. :)