It seems that the above code is not... perfect. This setup wants to glitch very rarely, but when it does it is disastrous.
I've been doing a lot of research and work on this PS/2 Keyboard connection, and I found that my previous models using other logic methods were good, but only good for my specific keyboard speed. I would adjust the timing to fit what is needed, not too fast and not too slow. I have other keyboards, and they seem to work too, but the specs for PS/2 Keyboards have a wide range of speeds.
To accommodate for any keyboard speed I went back to this style. And so I did even more research and study while using this particular method. What I am finding is that (at least on my board) a clock signal goes missing sometimes. This might not happen in different setups, specifically using a VIA. But the idea is that IF there is a glitch in the system, the host computer sends a command to the keyboard to 'resend the last code'. With my setup here, I am incapable of doing that.
To work around it, I made this code:
Code:
; /NMI = Keyboard-Clock
; /IRQ = Keyboard-Data
vector_nmi
PHA
LDA #$FF
CLI
NOP ; for safety
NOP
vector_nmi_read
DEC key_counter
BEQ vector_nmi_code
PHA
LDA key_counter
CMP #$FF
BEQ vector_nmi_parity
CMP #$FE
BEQ vector_nmi_stop
PLA
PHA
EOR key_parity
STA key_parity
PLA
ROR A
ROR key_data
PLA
RTI
vector_nmi_code
PHA
EOR key_parity
STA key_parity
PLA
ROR A
ROR key_data
LDA key_data
STA key_code
PLA
RTI
vector_nmi_parity
PLA
CMP key_parity
BEQ vector_nmi_parity_error
PLA
RTI
vector_nmi_parity_error
PHX
LDA #$00 ; null
LDX key_write
STA key_array,X
INC key_write
PLX
LDA #$09
STA key_counter
STZ key_parity
STZ key_data
PLA
RTI
vector_nmi_stop
PLA
BEQ vector_nmi_stop_error
PHX
LDA key_code
LDX key_write
STA key_array,X
INC key_write
PLX
LDA #$09
STA key_counter
STZ key_parity
STZ key_data
PLA
RTI
vector_nmi_stop_error
PHX
LDA #$00 ; null
LDX key_write
STA key_array,X
INC key_write
PLX
LDA #$08
STA key_counter
STZ key_parity
STZ key_data
PLA
RTI
vector_irq
PLA
PLA
PLA
LDA #$00
JMP vector_nmi_read
The changes are that I am actually checking for parity and stop bits. I am not checking for start bits because that's too early in the byte sequence to do anything, and it will change the parity anyways since the normal start bit is always 0 and does not change parity. The folks who designed this 11 bit sequence were genius in that all instances of error would either fall on the parity bit or the stop bit. You must check both!
And I am happy to report that this seems to be working better. I don't know if I'd call it 'glitch free'. But I've been having it display when it does find a 'glitch' and I cannot tell when I was typing. I suppose I would miss a key, but heck, I do that all the time when typing anyways, so it goes nearly unnoticed.
There's the update. I know most of you won't be interested in implementing this radically "simple" hardware method, but I must say I learned a great deal about signal integrity and parity bits! If I decide to update the code in a significant way I will update y'all here. Thank you!
Chad
EDIT:
Had a talk with Bill (plasmo) and he said he had been having trouble with how slow the keyboard clock's falling edge was. Perhaps that is what was happening to me too? I think that if I had tried to buffer the signal through a 74HC14 schmitt-trigger vs the 74HC04 I had used, it might have worked.
Either way, I'm abandoning this particular setup for the keyboard in favor of some minimal logic changes that seem to work well. Just wanted to show a conclusion, thanks everyone.