Keyboard replacement

Modern, Memotech inspired, hardware projects
Tony Brewer
Posts: 108
Joined: 08 Jan 2014 20:50

Re: Keyboard replacement

Post by Tony Brewer »

Bill B wrote: Cog 3
This cog reads the state of the MTX keyboard drive lines, and outputs the the selected row of the in-memory keyboard model to the sense lines. The MTX Z80 writes the drive lines with one instruction, and reads the sense lines with the very next instruction. With a real keyboard the sense lines update instantly (or at least at the speed of light). The Propeller is significantly faster than the Z80 but updating the sense lines in time is still a challenge. In order to achieve this, it has to be assumed that only one drive line is active at any one time. This is always true for the MTX ROM, but may not be true for all games that implement their own keyboard decoding. The Propeller code uses a binary search to identify the active drive line. This enables the required keyboard row to be selected using only three tests.
An interesting project.

The Speculator used nine bytes of the 6116 SRAM for reading/writing data for the eight key rows, one byte for each individual row and the ninth for all rows selected at the same time, which is commonplace in Spectrum code for detecting any key press (followed by row testing). I don't know whether MTX games did this too, but if they did the software priority encoder in cog 3 is likely to miss key presses. A preliminary drive line zero test would solve this problem, if it really exists and there is time for the extra test.
Last edited by Tony Brewer on 13 Feb 2018 02:17, edited 1 time in total.
Bill B
Posts: 590
Joined: 26 Jan 2014 16:31

Re: Keyboard replacement

Post by Bill B »

Tony,

The MTX ROM certainly only activates one drive line at a time. Not being a game programmer / player I don't have any real feel for whether games might activate multiple drive lines. Perhaps Dave's trials might identify any issues.

It would not be too expensive to add one more test for all eight drive lines active and return a result for that case. From Martin's calculations there should be time with the 4MHz Z80 in an MTX. Even without that extra test, the MTX+ at full speed will require wait states.

One option that has occurred to me is that with eight drive lines there are only 256 possible drive states (one of which is trivial). If cog 1 calculated the sense status for all these possible drive states, then cog 2 could select and return the required result in time. There are two possible issues with this approach:
  • The amount of time needed to update all 256 states on each key press or release
  • The possibility of inconsisencies if the MTX reads the keyboard while the Propeller (cog 1) is part way through updating all the possible sense states.
User avatar
Dave
Posts: 1278
Joined: 11 Aug 2012 18:16
Contact:

Re: Keyboard replacement

Post by Dave »

"Not being a game programmer / player I don't have any real feel for whether games might activate multiple drive lines. Perhaps Dave's trials might identify any issues."

I don't play many games myself either, but from what I have seen so far with a couple of games, the keyboard copes with 2 key presses OK. In Qogo, you move diagonally using two arrow keys and that works fine. Other games that use the direction keys and fire button simultaneously (like Phaid and Spectron) work OK too. I have not specifically checked which drive lines are being used though.

If anyone knows of any games that use lots of simultaneous key actions, I could try those too, but so far, the PS/2 keyboard seems to work very well

regards
Dave
Tony Brewer
Posts: 108
Joined: 08 Jan 2014 20:50

Re: Keyboard replacement

Post by Tony Brewer »

Some more thoughts on this "exciting" project:

1. If the Propeller system clock is 16 x 6 MHz = 96 MHz, I think a cog could output the sense lines correctly if any or all of the eight drive lines change. There is over 2 us @ 4 MHz between an OUT and an IN and I calculate the worst-case Propeller response at about 1.5 us, assuming the 96 MHz clock.

2. Why worry about PS/2 and USB pins being shared? There are plenty of pins on the Propeller for separate I/O.

3. If USB works best on P00 and P01, then I recommend KB0-KB9 on pins P02-P11. I don't understand why the order is reversed on the USB schematics.

4. If one of the Port 7 outputs is also connected to the Propeller as a keyboard/other select input, then ports 5 and 6 could be used as more general-purpose 8-bit output and 10-bit input ports, much better than the rather useless Port 7 PIO on its own. The Propeller might even be able to act as a USB controller for things other than keyboards.
Last edited by Tony Brewer on 14 Feb 2018 00:23, edited 3 times in total.
User avatar
Dave
Posts: 1278
Joined: 11 Aug 2012 18:16
Contact:

Re: Keyboard replacement

Post by Dave »

Hi Tony,

"exciting" as there is not much else going on that the moment :)

The order of KB0-9 is reversed on the USB schematics as that made for easier routing of the PCB. It's not essential, just neater and alignes with the MTX pinout.

Martin did suggest using some of the capability of Port 7 as that is going to be easy to do if we are getting power from there anyway. Martin did suggest a mouse input, but I couldn't see a real use for it and we may not have had enough I/O pins anyway. That is up for debate though?

regards
Dave
Tony Brewer
Posts: 108
Joined: 08 Jan 2014 20:50

Re: Keyboard replacement

Post by Tony Brewer »

Hello Dave,

Although I'm sure something more exciting will happen in 2018, this project is quite exciting.

I think the best option is USB on P00-P01, KB0-9 on P02-P11, DR0-7 on P12-19 and PS/2 on two other pins. The software would run quickest with the first KB pin no higher than P02. Swapping KBx and Kx on the schematic would be more compatible with the MTX circuit diagrams.

Below is my Propeller code for outputting to the sense lines. No guarantees it is complete and error-free.

Code: Select all

' add012, add345 & add67 are three registers that hold
' hub addresses which have packed key bit data as follows:
'
' (add012)  bits  0-9  = KB0-9 drive 0
'           10-19 = KB0-9 drive 1
'           20-29 = KB0-9 drive 2
'           30-31 = unused
'
' (add345)  bits  0-9  = KB0-9 drive 3
'           10-19 = KB0-9 drive 4
'           20-29 = KB0-9 drive 5
'           30-31 = unused
'
' (add67)   bits  0-9  = KB0-9 drive 6
'           10-19 = KB0-9 drive 7
'           20-31 = unused
'
' Rotate all bits left by two bits if USB on P00 and P01
'
sensepins   long   %1111111111          ' sense pins are 0-9 (for prototype)
drivepins   long   %11111111 << 10      ' drive pins are 10-17 (for prototype)
sensehigh   long   %1111111111          ' bits 0-9 all high (too large for immediate)
sense       long   0                    ' holds sense output value
drive       long   0                    ' holds drive input value
add012      long   ?                    ' holds hub address x
add345      long   ?                    ' holds hub address x + 1
add67       long   ?                    ' holds hub address x + 2
key67
key012      long   0                    ' holds packed key bits from (add012) or (add67)
key345      long   0                    ' holds packed key bits from (add345)
'
start       mov     dira,sensepins
loop        mov     sense,sensehigh
            and     drive,drivepins
            waitpne drive,drivepins     ' wait for new DR0-7 after OUT 5
            rdlong  key012,add012
            mov     drive,ina
            ror     drive,#10           ' needed as ror a,b wc writes only a[0] to c
            ror     drive,#1   wc
   if_nc    and     sense,key012        ' drive 0
            ror     key012,#10
            ror     drive,#1   wc
   if_nc    and     sense,key012        ' drive 1
            ror     key012,#10
            ror     drive,#1   wc
   if_nc    and     sense,key012        ' drive 2
            rdlong  key345,add345       ' 48 clock cycles after rdlong 012
            ror     drive,#1   wc
   if_nc    and     sense,key345        ' drive 3
            ror     key345,#10
            ror     drive,#1   wc
   if_nc    and     sense,key345        ' drive 4
            ror     key345,#10
            rdlong  key67,add67         ' 32 clock cycles after rdlong 345
            ror     drive,#1   wc
   if_nc    and     sense,key345        ' drive 5
            ror     drive,#1   wc
   if_nc    and     sense,key67         ' drive 6
            ror     key67,#10
            ror     drive,#1   wc
   if_nc    and     sense,key67         ' drive 7
            mov     outa,sense
            ror     drive,#32-8-10      ' drive rotated 32 bits, back to original value
            jmp     #loop
Bill B
Posts: 590
Joined: 26 Jan 2014 16:31

Re: Keyboard replacement

Post by Bill B »

Tony,

Interesting. It had not occurred to me to pack the results from multiple scan rows in order to minimise reads from hub RAM. This will be slower than what we currently have, but probably still OK for the MTX. For the MTX+ at full speed it will increase the number of wait states required.

I had suggested above connecting USB and PS/2 keyboards to separate pins. The question then is, do you want to allow the possibility of them both being active?

When counting Propeller pins, it should be noted that the keyboard code needs one pin to signal changes to the keyboard matrix. This triggers updating of the sense lines, even if the drive status does not change. This pin, as a side effect, provides the keyboard activity LED. The USB driver also requires a N/C pin for similar intra-cog signalling.

As for supporting other USB divices it has to be remembered how demanding the USB protocol is. I am still amazed theat the Propeller can do it at all. The existing driver has a number of limitations:
  • Strictly one device, directly connected, no hub.
  • It reqires three pins out of the bottom eight, D+, D- and one N/C for intra-cog signalling. So a maximum of two USB devices.
  • Each device would require its own instance of the driver, each using three cogs. So again a maximum of two devices.
  • The driver only provides the lowest level of USB protocol. It is necessary to implement the higher levels on top of that for any specific device.
User avatar
Dave
Posts: 1278
Joined: 11 Aug 2012 18:16
Contact:

Re: Keyboard replacement

Post by Dave »

Hi Tony & Bill

Thanks for the continued work on this.

If I understand it correctly, Tony's suggested code allows multiple key presses to be more reliably detected as the cost of some speed?

Based on the (very) limited testing that I have done, there seems to be very few games on the basic MTX that use multiple key detection and those seem to work ok with the current code. It may be more reliable to use the faster code and accept that there may be some games that might struggle on an MTX? As Bill say's, MTXPlus+ will likely need wait states anyway.

I can't see the need to cater for both types of keyboard being active concurrently. I think it highly unlikely that people would need or want to plug two additional keyboards in. It strikes me of solving a problem that doesn't really exist?

My preferred option would be to use a single pair of pins with the jumper selection we discussed previously, though that does need testing when we have the USB code to see if we can use a single set of resistor values. If different resistors are needed, we can either solve it with jumpers or use different pins for USB and PS/2.

Martin - what are your thoughts?
regards
Dave
Bill B
Posts: 590
Joined: 26 Jan 2014 16:31

Re: Keyboard replacement

Post by Bill B »

Dave,

The issue is not multiple keys pressed simultaneously. Existing code will cope with that. The problem comes with any games that activate more than one keyboard matrix drive lines at the same time. Tony suggested that some games may do that to speed detection of "any key" presses.
Tony Brewer
Posts: 108
Joined: 08 Jan 2014 20:50

Re: Keyboard replacement

Post by Tony Brewer »

Bill B wrote:Tony,

Interesting. It had not occurred to me to pack the results from multiple scan rows in order to minimise reads from hub RAM. This will be slower than what we currently have, but probably still OK for the MTX. For the MTX+ at full speed it will increase the number of wait states required.

When counting Propeller pins, it should be noted that the keyboard code needs one pin to signal changes to the keyboard matrix. This triggers updating of the sense lines, even if the drive status does not change. This pin, as a side effect, provides the keyboard activity LED. The USB driver also requires a N/C pin for similar intra-cog signalling.

As for supporting other USB divices it has to be remembered how demanding the USB protocol is.
Bill, do you mind posting the Propeller code relevant to the MTX interface? (Drive and sense lines, not key codes/translation.) I've made a sentence bold above which I don't understand fully.
Last edited by Tony Brewer on 16 Feb 2018 19:59, edited 1 time in total.
Post Reply