On 1/2/2022 at 9:13 AM, EMwhite said:
Getting back to on-topic of this thread, why is supporting PS/2 so difficult? Is it that the rest of the architecture of the orig. X16 does not play well with PS/2?
It seems peculiar that others have implanted PS/2 kbd. and mouse with zero fanfare or difficulty and X16 is awaiting the return [to the project] of one person (I don’t know the name is the person, somebody that wrote the kernel I believe).
I'm mostly interested in the hardware on this project, but your prompted me to look into the PS/2 code. I think we are seeing the result of two factors in the way the X16 handles PS/2:
KERNAL inhibits PS/2 communication except when servicing the keyboard.
KERNAL polls for a fixed time after resuming PS/2 communication.
The code for this is in kernal/drivers/x16/ps2.s:
[code]
ps2_receive_byte:
; set input, bus idle
lda port_ddr,x ; set CLK and DATA as input
and #$ff-bit_clk-bit_data
sta port_ddr,x ; -> bus is idle, keyboard can start sending
lda #bit_clk+bit_data
ldy #10 * mhz
: dey
beq lc08c
bit port_data,x
bne :- ; wait for CLK=0 and DATA=0 (start bit)
[/code]
That "ldy #10 * mhz" is the delay. In this case it is 10 * 8 = 80 loops. The last 4 lines are executed 80 times waiting to see the PS/2 start condition (both CLK and DATA going low). If there is no start condition, the code re-inhibits communication and returns. I do not believe that the PS/2 spec provides a guarantee for how long after the host resumes communication before the device must send a start a bit if it has data ready. The device itself probably has an always running PS/2 clock so it probably won't send the start bit until the clock after it detects that the host has de-inhibited traffic.
I suspect that this is the problem hitting the X16. At higher frequency, 80 loops is not a long enough delay
for some keyboards. After seeing nothing for 80 loops, KERNAL re-inhibits the device before it has had a chance to send a start bit. At 2MHz, the delay is 4x longer and is an adequate delay, again,
for some keyboards. This inhibit/poll solution is not what the PS/2 interface was designed for. Inhibiting communication is expected to be a rare event (e.g. during BIOS/UEFI initialization at system BOOT). The keyboard needs to be attached to a controller that doesn't keep communication inhibited and is ready to consume data when it is available. In other words - it needs a dedicated controller or a host keyboard handler that is interrupt driven.
The issue might be fixed for now by changing the loop count from 10 * mhz to 40 * mhz.