Reading the keyboard by direct hardware access

From Retrosoftware

(Difference between revisions)
Jump to: navigation, search
(New page: = Reading the keyboard by direct hardware access =)
Line 1: Line 1:
 +
''[[SampleCodeLibrary|Sample Code Library]] > Reading the keyboard by direct hardware access''
 +
 +
= Reading the keyboard by direct hardware access =
= Reading the keyboard by direct hardware access =
 +
 +
This is a topic which is barely, if at all, explained in the AUG, and indeed it was an area which caused some of the biggest problems in the first BBC emulators, mostly because it seemed no-one could find any good documentation on it!
 +
 +
But it turns out that, with some initial setup, reading whether a key is pressed or not by accessing the keyboard hardware directly is extremely trivial on the Beeb.
 +
 +
 +
== Doing it 'legally' ==
 +
 +
 +
 +
== Doing it the dirty way ==
 +
 +
The keyboard is mapped to System VIA port A (accessed through &FE41 or &FE4F for "no handshake", whatever the hell that means...). The bottom 7 bits are used to specify which key you wish to poll, and the top bit returns whether the key is pressed or not.
 +
 +
So, first we need to set the Data Direction Register A to specify that the bottom 7 bits are outputs, and the top bit is an input. Hence:
 +
 +
<tt>
 +
LDA #&7F:STA &FE43
 +
</tt>
 +
 +
Now, System VIA port A is also shared by the sound chip and the speech chip, so before we can access the keyboard, we need to enable it over the other two possibilities. This is done via the "addressable latch" in System VIA port B.
 +
 +
The addressable latch controls a miscellany of "stuff" (AUG page 419) - there's a further layer of indirection here: we have to set up the bottom 4 bits of System VIA port B as outputs, and then we write the "bit number" of the addressable latch bit we wish to write in bits 0-2, and the value to write in bit 3.
 +
 +
To enable keyboard we have to pull bit 3 of the addressable latch low, so here's how we do this:
 +
 +
<tt>
 +
LDA #&0F:STA &FE42 \ allow write to addressable latch
 +
LDA #&03:STA &FE40 \ set bit 3 to 0
 +
</tt>
 +
 +
So, that's all the initialisation we need to do.
 +
 +
 +
Now, reading a key is simplicity itself! We need the internal key number of the key - either consult the table on AUG page 142, or take the negative INKEY code of the key, make it positive, and subtract 1. (e.g. space (-99) becomes 98).
 +
 +
Then, write to System VIA port A, and read it back. The top bit will tell you whether the key is pressed or not (set=pressed):
 +
 +
<tt>
 +
LDA #97:STA &FE4F:LDA &FE4F \ N flag = whether 'Z' pressed
 +
</tt>
 +
 +
 +
All of this has to be done either with interrupts disabled, or a custom IRQ handler in place which doesn't let the OS in, otherwise all of the setup will be undone by OS code (because these values are changed to play sounds, for example).
 +
 +
And that's it! How to read a key in 14(ish) clock cycles.

Revision as of 08:32, 28 June 2008

Sample Code Library > Reading the keyboard by direct hardware access


Reading the keyboard by direct hardware access

This is a topic which is barely, if at all, explained in the AUG, and indeed it was an area which caused some of the biggest problems in the first BBC emulators, mostly because it seemed no-one could find any good documentation on it!

But it turns out that, with some initial setup, reading whether a key is pressed or not by accessing the keyboard hardware directly is extremely trivial on the Beeb.


Doing it 'legally'

Doing it the dirty way

The keyboard is mapped to System VIA port A (accessed through &FE41 or &FE4F for "no handshake", whatever the hell that means...). The bottom 7 bits are used to specify which key you wish to poll, and the top bit returns whether the key is pressed or not.

So, first we need to set the Data Direction Register A to specify that the bottom 7 bits are outputs, and the top bit is an input. Hence:

LDA #&7F:STA &FE43

Now, System VIA port A is also shared by the sound chip and the speech chip, so before we can access the keyboard, we need to enable it over the other two possibilities. This is done via the "addressable latch" in System VIA port B.

The addressable latch controls a miscellany of "stuff" (AUG page 419) - there's a further layer of indirection here: we have to set up the bottom 4 bits of System VIA port B as outputs, and then we write the "bit number" of the addressable latch bit we wish to write in bits 0-2, and the value to write in bit 3.

To enable keyboard we have to pull bit 3 of the addressable latch low, so here's how we do this:

LDA #&0F:STA &FE42   \ allow write to addressable latch
LDA #&03:STA &FE40   \ set bit 3 to 0

So, that's all the initialisation we need to do.


Now, reading a key is simplicity itself! We need the internal key number of the key - either consult the table on AUG page 142, or take the negative INKEY code of the key, make it positive, and subtract 1. (e.g. space (-99) becomes 98).

Then, write to System VIA port A, and read it back. The top bit will tell you whether the key is pressed or not (set=pressed):

LDA #97:STA &FE4F:LDA &FE4F  \ N flag = whether 'Z' pressed


All of this has to be done either with interrupts disabled, or a custom IRQ handler in place which doesn't let the OS in, otherwise all of the setup will be undone by OS code (because these values are changed to play sounds, for example).

And that's it! How to read a key in 14(ish) clock cycles.