gfoot wrote:
What are the signals hooked up to the oscilloscope in each trace?
I would:
- not disable the SR - leave it active all the time
- read twice, capturing all the bits, storing two bytes separately
- read from the SR as soon as possible in the ISR, to reduce the chance that it shifts again before you read from it
- maybe initially just make the ISR read and store the bytes in a buffer so you can inspect them afterwards, check that works well first before you try to automatically check or decode them
On point 2, if the keyboard sends for example $74, I believe that's encoded as 0:00101110:1:1 so if you read the shift register after bit 8 and again after bit 11 then you should get 00010111 followed by 10111011, with five bits overlapping. You can check successful reception in a lot of ways based on this - the start bit, the stop bit, the parity bit, and the 5 overlapping bits between the two bytes.
One option for timing your reads is to let the SR interrupt fire after 8 bits, using that to trigger the first read, and use T2 to count 11 bits to trigger the second read. It may be simpler than resetting T2 in a hurry during the transmission and allows you to use two fairly separate routines for handling the two types of interrupt.
Something else to consider is framing - making sure you are reading the 11 bits in sync with the keyboard, not offset. You could deliberately skip an extra bit if the parity, start, or stop bit checks fail, for example, to make it self-correct. Another approach could be using T1 to flush the system after an appropriate delay, which would probably be quite a reliable catch-all solution.
First and foremost though, going back to point 4 above, I'd probably start by just setting up to read the SR based on its own interrupt after each 8 bits, make a simple ISR that just captures the first 256 eight-bit sequences into a buffer, and inspect the data by hand to make sure the electronics side is all sound. This will cover things like the clock edge issue, and perhaps the external clock bug in the 6522. Then you could go back to more complex processing.
Thanks for the help, G! I tried most of your suggestions but eventually decided to fix what I knew needed fixing anyway.
Turns out the mode011-bug was more common than I thought. Adding a 74'74 immediately solved the issue and since the bit is shifted in on the rising edge the inverter isn't needed - I believe PS/2 data doesn't change until somewhere near the end of the high time anyway.
I still need to disable the shift register to make it work though. If I remember correctly the IRQ flag is still set, even it is disabled and doesn't pull down ~IRQ - so maybe some other IRQ flags need handling. When doing a quick check I see CB1 and SR flags set even though they are disabled.
My SBC looks so naked with PORTA unpopulated XD
Quote:
;kbshift initialized to $0A
t2_irq:
txa
pha
lda #$81
sta $5000 ; Ouput only register debug
LDA #%01100000
STA ACR ; T1 continuous - disable Shift register
lda SR1 ;
sta $0b ; LSB is in MSB :/
;No loop to save cycles - temporary measure until I remap the keymap.
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
rol ; MSB to C
ror $0c ; C to MSB
lda kbshift ; If we count 11(10 + one we miss?) falling edges we should end up at the same index in the shifted data
sta T2CL
lda #0
sta T2CH
lda #1
sta $5000 ; OOR debug
LDA #%01101100
STA ACR ; T1+T2, reenable Shift register
;pla
;rti
keyboard_interrupt:
; Convert scancode to ascii and add to buffer here
The scope capture is PS/2 clock and the debug bit 8 on the $5000 output register. The ISR is horribly long but when I convert the keymap to LSB in MSB the juggling is fixed.
It's a bit frustrating that the '74 also breaks sending data to the keyboard - now I need to add a 74'126 tristate buffer if I want two way transfer.. But I guess it's still better than two '595's a '14 and a few passives.
Still some grunt work to do...