Close

The mental perils of pin sharing

A project log for ABN6502 SBC R1

Saving the planet, one obsolete chip at a time

anders-nielsenAnders Nielsen 05/05/2022 at 20:131 Comment

This one might get... technical. I will probably share the light version in a future video. TL;DR - I made a better PS/2 interface but got greedy while optimizing. 

Let's start off with a success.. I did it! I actually did it! I got rid of all three components for interfacing the PS/2 keyboard, I got back all of the 6522's port A, including CA1 and CA2, and all it took in return was one half of a 74hc74, some time on the 6522 VIA shift register... and PB6.

This magical pin can count negative pulses and only interrupt the CPU after x pulses have passed. Since the shift register on the 6522 insists that 8 and only 8 shifts is the correct number of shifts for an IRQ, PB6 can take over this job of counting the shift register clocks(together with CB1 - not replacing it) and suddenly the shift register can be used to filter out the correct 8 bits of an arbitrary number of bits. For PS/2 - this number is 11. 

You might say I'm throwing away the parity, start and stop bits for no reason, and sure - that can probably be avoided with this trick as well - but I chose the extra complexity and IRQ's aren't worth it for now. And luckily it's only a software change if I decide I need the error checking bits later - I can use the SR IRQ for the first eight bits and grab the remaining three with the PB6 IRQ, or even alternate the number of PB6 bits. 

The reason I need the 74hc74 between the PS/2 clock line and CB1 shift register clock is two-fold. First, all 6522's have a bug where external shift register clocks are ignored if they coincide with the falling edge of PHI2, hence the 74hc74 can save the day by only changing the PS/2 clock line on the rising edge of PHI2. Crisis avoided. Second, the inverted output of the '74 is better suited as the clocking edge for PS/2 data since it should be sampled on the rising edge instead of the falling edge. Yay for free inverters!

And best of all - since PB6 is on the keyboard side of the '74, it can be used to hold down the PS/2 clock line and initiate computer -> keyboard data transfer, with a simple mode change of the shift register! Yay for blinky lights on keyboards!

You might have caught on as to what perils the title of this post refers to by now... PB6 is already in use on the board. Not only is it in use, it's also an output, instead of an input. 

So far I've been using it as the MISO pin for SPI and that's worked out fantastically since it's pretty fast to sample pin 6 with the BIT instruction - so SPI might be slow, but not really that slow considering it's supposed to be a "late 1970's computer".

I couldn't let it go though. I tumbled down the rabbit hole as I tried to multiplex the poor PB6. 

In theory very simple - just leave the pin as an input for the PS/2 clock while not using SPI and then toggle it to an output when it's time to use SPI, right? 

Turns out it's not that simple to juggle code, when you not only have to toggle the data direction register but also have to make sure the shift register isn't clocking while using SPI, and you also have to make sure T2 isn't counting down from PB6 edges, and you also have to make sure the right interrupts are disabled... And then do it all over again to enable the disabled things after every SPI byte..

After the success of saving IC's and ports that was previously tied up for PS/2 I couldn't just let it go though, and I was thirsty for more. .. I didn't want to take up another PIN! ... so I started juggling, I started debouncing my polling of the nRF24l01 circuit, I started littering the ROM code with resets of the T2 counter, I left in extra SEI's and CLI's, I was seeing my screen fill up with misaligned characters, the keyboard not working, then working, frantically enabling debug output to the screen... And getting no help. 

And here I am. It's over.  I will cut the traces to MOSI and MISO tomorrow. MOSI is going to PB7 where it will later share it's time with output to the tape interface. MISO is quietly moving over to the unused PB5 I have no idea what I was saving for. Yay for jumpers!
And the code I have so desperately tried to fix and save? A BIT and a BPL, has turned into an LDA, an AND and a BEQ for a total of two 2 MHz cycles extra. 

Let this be a reminder: Don't spend hours trying to save one microsecond. You might be able to save the microsecond - you will never get the hours back. 

Discussions

Ken Yap wrote 05/05/2022 at 22:24 point

Never mind, at least you got a war story out of it. 👍 I think we have all attempted over-optimisation at some time or other only we didn't realise it until the bitter end.

  Are you sure? yes | no