Discussion:
KBC challenge
(too old to reply)
James Harris
2021-04-14 14:15:26 UTC
Permalink
Are you up for a challenge?

How well do you know what the keyboard controller does? By KBC I mean
the chip which is the middle part of

host <---> KBC <---> keyboard

where the host is the CPU which runs our code and the link from the KBC
to the keyboard could be a PS/2 cable.

Some background on the KBC can be found at

http://aodfaq.wikidot.com/kbc-commands.

KBC operations have always been a bit of a black box to me with /many/
uncertain areas. And from the vagueness of what I've read in supposedly
authoritative sources it has seemed that others are also unsure of the
details.

Perhaps part of the problem is that the 8042 chip which was used as a
KBC is not really a KBC. It is, in fact, a microcontroller. It only
becomes a KBC when it runs a certain piece of firmware. As a result, the
KBC's operation is not documented in a datasheet such as it would be if
it was a dedicated chip.

Thankfully, some brave soul has made an effort to understand the
firmware in the ROM of an early incarnation and posted his findings at

http://www.halicery.com/8042/8042_1503033.TXT
http://www.halicery.com/8042/8042_INTERN.TXT

I've been reading the disassembly to try to find out the answers to some
knotty questions.

Before I post my interpretations (and I wouldn't claim them to be more
than that as reading the 8042 code is far from easy) you might fancy the
challenge of trying your hand at some of the questions. Feel free to
post what you think happens or what you think /should/ happen. Hopefully
us having a discussion about it will give us all a better understanding
of how to handle KBC and keyboard in an OS.

Here are the questions.


What does command 0x20 do?

What does command 0x00 do?

Command 0xAA (self test) returns 0x55 on success but what does it return
if the self test fails?

If the KBC is sent a command which it doesn't recognise what does it do?

As the KBC is not multitasking what happens if the host sends it a
command while it is in the middle of receiving a byte from the keyboard?

If the KBC gets a parity error when receiving a byte from the keyboard
what does it do?

What does the KBC do if it detects a failure when sending a byte to the
keyboard?

We know that when the KBC receives a byte from the keyboard it signals
an interrupt on IRQ1 but is an interrupt generated when the KBC itself
has something to send the host, perhaps in response to a command?


It was trying to find an answer to the last question which led to me
reading more of the disassembly.
--
James Harris
wolfgang kern
2021-04-14 20:43:21 UTC
Permalink
Post by James Harris
Are you up for a challenge?
How well do you know what the keyboard controller does? By KBC I mean
the chip which is the middle part of
 host  <--->  KBC  <--->  keyboard
where the host is the CPU which runs our code and the link from the KBC
to the keyboard could be a PS/2 cable.
Some background on the KBC can be found at
 http://aodfaq.wikidot.com/kbc-commands.
KBC operations have always been a bit of a black box to me with /many/
uncertain areas. And from the vagueness of what I've read in supposedly
authoritative sources it has seemed that others are also unsure of the
details.
Perhaps part of the problem is that the 8042 chip which was used as a
KBC is not really a KBC. It is, in fact, a microcontroller. It only
becomes a KBC when it runs a certain piece of firmware. As a result, the
KBC's operation is not documented in a datasheet such as it would be if
it was a dedicated chip.
Thankfully, some brave soul has made an effort to understand the
firmware in the ROM of an early incarnation and posted his findings at
 http://www.halicery.com/8042/8042_1503033.TXT
 http://www.halicery.com/8042/8042_INTERN.TXT
I've been reading the disassembly to try to find out the answers to some
knotty questions.
Before I post my interpretations (and I wouldn't claim them to be more
than that as reading the 8042 code is far from easy) you might fancy the
challenge of trying your hand at some of the questions. Feel free to
post what you think happens or what you think /should/ happen. Hopefully
us having a discussion about it will give us all a better understanding
of how to handle KBC and keyboard in an OS.
Here are the questions.
What does command 0x20 do?
What does command 0x00 do?
Command 0xAA (self test) returns 0x55 on success but what does it return
if the self test fails?
If the KBC is sent a command which it doesn't recognise what does it do?
As the KBC is not multitasking what happens if the host sends it a
command while it is in the middle of receiving a byte from the keyboard?
If the KBC gets a parity error when receiving a byte from the keyboard
what does it do?
What does the KBC do if it detects a failure when sending a byte to the
keyboard?
We know that when the KBC receives a byte from the keyboard it signals
an interrupt on IRQ1 but is an interrupt generated when the KBC itself
has something to send the host, perhaps in response to a command?
It was trying to find an answer to the last question which led to me
reading more of the disassembly.
you'll find all answers for the two controller variants in RBIL :)

and yes, IRQ_1 is raised after initialize and in response to all
commands as long KBD-IRQ isn't disabled.
__
wolfgang
James Harris
2021-04-15 08:06:15 UTC
Permalink
...
Post by wolfgang kern
Post by James Harris
We know that when the KBC receives a byte from the keyboard it signals
an interrupt on IRQ1 but is an interrupt generated when the KBC itself
has something to send the host, perhaps in response to a command?
It was trying to find an answer to the last question which led to me
reading more of the disassembly.
you'll find all answers for the two controller variants in RBIL :)
All answers?

In fact, I took a look at RBIL as you make a good suggestion. But what
do you make of the first line of table P0401? In my copy it says:

(Table P0401)
Values for keyboard controller commands (data goes to PORT 0060h):
Value Description
20h read read byte zero of internal RAM, this is the last KB command
sent to the 8041/8042

Is that description right?

More to the point, though, which section of RBIL were you referring to?
Post by wolfgang kern
and yes, IRQ_1 is raised after initialize and in response to all
commands as long KBD-IRQ isn't disabled.
From what I read in the disassembly I think that's correct, and it came
as a surprise to me. I expected that responses to commands would come in
via polling so that the interrupt stream was just the bytes from the
keyboard. But it turns out that the keystrokes and responses need to be
separated from each other after receipt.
--
James Harris
wolfgang kern
2021-04-15 14:46:04 UTC
Permalink
Post by James Harris
...
Post by wolfgang kern
Post by James Harris
We know that when the KBC receives a byte from the keyboard it
signals an interrupt on IRQ1 but is an interrupt generated when the
KBC itself has something to send the host, perhaps in response to a
command?
It was trying to find an answer to the last question which led to me
reading more of the disassembly.
you'll find all answers for the two controller variants in RBIL :)
All answers?
In fact, I took a look at RBIL as you make a good suggestion. But what
(Table P0401)
Value           Description
20h    read    read byte zero of internal RAM, this is the last KB command
                 sent to the 8041/8042
Is that description right?
hard to tell, cmd-readback option may or not be implemented.
Post by James Harris
More to the point, though, which section of RBIL were you referring to?
I have two older RBIL sources, section PORTS [60,64] and the INT-list.
Post by James Harris
Post by wolfgang kern
and yes, IRQ_1 is raised after initialize and in response to all
commands as long KBD-IRQ isn't disabled.
From what I read in the disassembly I think that's correct, and it came
as a surprise to me. I expected that responses to commands would come in
via polling so that the interrupt stream was just the bytes from the
keyboard. But it turns out that the keystrokes and responses need to be
separated from each other after receipt.
that's easy, everything >E1 is either a cmd respond or an error.
the only exception is the initial type identifier (IIRC 41/A1 ?) but
this wont occur during normal use.
__
wolfgang
James Harris
2021-04-16 12:17:24 UTC
Permalink
Post by wolfgang kern
Post by James Harris
...
Post by wolfgang kern
Post by James Harris
We know that when the KBC receives a byte from the keyboard it
signals an interrupt on IRQ1 but is an interrupt generated when the
KBC itself has something to send the host, perhaps in response to a
command?
It was trying to find an answer to the last question which led to me
reading more of the disassembly.
you'll find all answers for the two controller variants in RBIL :)
All answers?
In fact, I took a look at RBIL as you make a good suggestion. But what
(Table P0401)
Value           Description
20h    read    read byte zero of internal RAM, this is the last KB command
                  sent to the 8041/8042
Is that description right?
hard to tell, cmd-readback option may or not be implemented.
I think that's it. It's been puzzling me as to what it meant because
I've never heard of the KBC letting the host read back the last command.
In fact, in my drivers for various chips I keep a copy of the last byte
sent to each port. Then it that byte's value can be reported back, can
appear in dumps, and can sometimes be used to prevent unnecessary port IO.

But I see at

http://aodfaq.wikidot.com/kbc-commands

that command 0x20 reads the "command byte". And the command byte is what
controls or reports a number of operational states of the KBC. It is not
the last byte written to the command port.

In other words, whoever wrote the above in RBIL got it wrong. But to put
it in context I think that's the first error I've ever noticed in RBIL.

And the term "command byte" is not the clearest name that was ever
chosen. Control Byte or Operation Byte might have been better.
Post by wolfgang kern
Post by James Harris
More to the point, though, which section of RBIL were you referring to?
I have two older RBIL sources, section PORTS [60,64] and the INT-list.
Post by James Harris
Post by wolfgang kern
and yes, IRQ_1 is raised after initialize and in response to all
commands as long KBD-IRQ isn't disabled.
 From what I read in the disassembly I think that's correct, and it
came as a surprise to me. I expected that responses to commands would
come in via polling so that the interrupt stream was just the bytes
from the keyboard. But it turns out that the keystrokes and responses
need to be separated from each other after receipt.
that's easy, everything >E1 is either a cmd respond or an error.
the only exception is the initial type identifier (IIRC 41/A1 ?) but
this wont occur during normal use.
I guess that's true if we limit what we send to the KBC but it's not the
case in general; at least that's how it seems though I am unsure what
translations, if any, are done to KBC responses.

For example, from the link above command 0xAB to test the keyboard
interface returns a number between zero and four.

IOW a general driver would have to separate keystrokes from other
responses. And I guess that's best done by inhibiting the keyboard
whenever we want to send the KBC a command to which it sends a response.

For the record it looks from the page, above, as though there are two
ways to disable the keyboard.

1. Command 0x60 to write a new Control Byte with the KB inhibit bit set.

2. Command 0xAD to tell the KBC to set the inhibit bit.

Keyboard IO is a messy business. :-(
--
James Harris
wolfgang kern
2021-04-16 15:39:50 UTC
Permalink
On 16.04.2021 14:17, James Harris wrote:
...
Post by James Harris
Post by wolfgang kern
Post by James Harris
(Table P0401)
Value           Description
20h    read    read byte zero of internal RAM, this is the last KB
command sent to the 8041/8042
Is that description right?
hard to tell, cmd-readback option may or not be implemented.
I think that's it. It's been puzzling me as to what it meant because
I've never heard of the KBC letting the host read back the last command.
In fact, in my drivers for various chips I keep a copy of the last byte
sent to each port. Then it that byte's value can be reported back, can
appear in dumps, and can sometimes be used to prevent unnecessary port IO.
Yeah me too keep a few (not all) data copies written to I/O.
Post by James Harris
But I see at
 http://aodfaq.wikidot.com/kbc-commands
a reliable source ?
Post by James Harris
that command 0x20 reads the "command byte". And the command byte is what
controls or reports a number of operational states of the KBC. It is not
the last byte written to the command port.
could be, I never checked what's in 60 after cmd 20,
seems just needed in quality control after chip-production.
Post by James Harris
In other words, whoever wrote the above in RBIL got it wrong. But to put
it in context I think that's the first error I've ever noticed in RBIL.
RBIL exists very long now and it may tell about things from the past ...
not necessarily wrong, don't you find this old stuff convenient :)
Post by James Harris
And the term "command byte" is not the clearest name that was ever
chosen. Control Byte or Operation Byte might have been better.
Post by wolfgang kern
Post by James Harris
More to the point, though, which section of RBIL were you referring to?
I have two older RBIL sources, section PORTS [60,64] and the INT-list.
Post by James Harris
Post by wolfgang kern
and yes, IRQ_1 is raised after initialize and in response to all
commands as long KBD-IRQ isn't disabled.
 From what I read in the disassembly I think that's correct, and it
came as a surprise to me. I expected that responses to commands would
come in via polling so that the interrupt stream was just the bytes
from the keyboard. But it turns out that the keystrokes and responses
need to be separated from each other after receipt.
that's easy, everything >E1 is either a cmd respond or an error.
the only exception is the initial type identifier (IIRC 41/A1 ?) but
this wont occur during normal use.
I guess that's true if we limit what we send to the KBC but it's not the
case in general; at least that's how it seems though I am unsure what
translations, if any, are done to KBC responses.
For example, from the link above command 0xAB to test the keyboard
interface returns a number between zero and four.
IOW a general driver would have to separate keystrokes from other
responses. And I guess that's best done by inhibiting the keyboard
whenever we want to send the KBC a command to which it sends a response.
For the record it looks from the page, above, as though there are two
ways to disable the keyboard.
1. Command 0x60 to write a new Control Byte with the KB inhibit bit set.
2. Command 0xAD to tell the KBC to set the inhibit bit.
sure, you must disable it while you alter its configuration
Post by James Harris
Keyboard IO is a messy business. :-(
there were (past tense) too many variants in the field, just look at
A20-gate and Master-reset and not to mention the PS/2 mouse addon.

I'm happy to made it work in my OS for PS/2 KBD+mouse. I didn't buy any
USB-keyboards yet and hope my stock hold long enough.
__
wolfgang
James Harris
2021-04-18 15:47:41 UTC
Permalink
...
Post by wolfgang kern
  http://aodfaq.wikidot.com/kbc-commands
a reliable source ?
Maybe not. But it agrees with

https://wiki.osdev.org/%228042%22_PS/2_Controller

...
Post by wolfgang kern
In other words, whoever wrote the above in RBIL got it wrong. But to
put it in context I think that's the first error I've ever noticed in
RBIL.
RBIL exists very long now and it may tell about things from the past ...
not necessarily wrong, don't you find this old stuff convenient :)
And the term "command byte" is not the clearest name that was ever
chosen. Control Byte or Operation Byte might have been better.
The osdev.org page calls it the Configuration Byte. I think that's a
good name.

In fact, any name is better than Command Byte.


...
Post by wolfgang kern
I'm happy to made it work in my OS for PS/2 KBD+mouse. I didn't buy any
USB-keyboards yet and hope my stock hold long enough.
Do you need stock? I see PS/2 keyboards for sale online.
--
James Harris
Rod Pemberton
2021-04-18 17:41:38 UTC
Permalink
On Sun, 18 Apr 2021 16:47:41 +0100
Post by James Harris
Post by wolfgang kern
  http://aodfaq.wikidot.com/kbc-commands
a reliable source ?
Maybe not. But it agrees with
https://wiki.osdev.org/%228042%22_PS/2_Controller
Did you cross-ref with

https://www.win.tue.nl/~aeb/linux/kbd/scancodes.html

--
James Harris
2021-04-19 08:56:32 UTC
Permalink
Post by Rod Pemberton
On Sun, 18 Apr 2021 16:47:41 +0100
Post by James Harris
Post by wolfgang kern
  http://aodfaq.wikidot.com/kbc-commands
a reliable source ?
Maybe not. But it agrees with
https://wiki.osdev.org/%228042%22_PS/2_Controller
Did you cross-ref with
https://www.win.tue.nl/~aeb/linux/kbd/scancodes.html
That looks like a good resource and it says the same. At

https://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kcc20

it says:

Command 0x20-0x3f: Read keyboard controller RAM

The last six bits of the command specify the RAM address to read. The
read data is placed into the output buffer, and can be read by reading
port 0x60. On MCA systems, type 1 controllers can access all 32
locations; type 2 controllers can only access locations 0, 0x13-0x17,
0x1d, 0x1f.
Location 0 is the Command byte,
--
James Harris
Rick C. Hodgin
2021-04-14 23:51:40 UTC
Permalink
On Wed, 14 Apr 2021 15:15:26 +0100
Post by James Harris
Are you up for a challenge?
How well do you know what the keyboard controller does? By KBC I mean
the chip which is the middle part of
host <---> KBC <---> keyboard
where the host is the CPU which runs our code and the link from the
KBC to the keyboard could be a PS/2 cable.
Somewhat unrelated, but I think very interesting ... there was a really
informative video published by Ben Eater on YouTube about the PS/2
keyboard interface:

So how does a PS/2 keyboard interface work?


Keyboard interface hardware


His next video should have the incoming codes decoded and his little
6502 project would have a PS/2 keyboard input. He shows a snippet
there at the end where it's working.

The entire project is available for his website so you can go through
the joy of creating your own computer from scratch on a breadboard.

He even created a horrible video adapter from scratch:
Video 1:

Video 2:

Video 3:

Video 4:


He explains things the best of anyone I've found online. And his
follow-along examples are really nice.
--
Rick C. Hodgin
James Harris
2021-04-21 11:04:46 UTC
Permalink
On 14/04/2021 15:15, James Harris wrote:

...
Post by James Harris
How well do you know what the keyboard controller does?
...
Post by James Harris
  http://www.halicery.com/8042/8042_1503033.TXT >   http://www.halicery.com/8042/8042_INTERN.TXT
... you might fancy the
challenge of trying your hand at some of the questions.
Here are my answers based on the above disassembly. The four-digit hex
values are addresses in the code so you can check.
Post by James Harris
What does command 0x20 do?
Sends the contents of the Command Byte at 0x20 to the host.
050D, 0559, and see RAM Memory Map
Post by James Harris
What does command 0x00 do?
Same as 0x20 by default. However, the address is offset by the byte at
0x2B, allowing the command to read any of the KBC's RAM even that
outside the 0x20-0x3F range.
050D, 0559, and see RAM Memory Map
Post by James Harris
Command 0xAA (self test) returns 0x55 on success but what does it return
if the self test fails?
Nothing.
0059, 0084

Tests such as at 070D jump to 004F on fail and it waits for more from host.

Therefore detection would have to be by timeout.
Post by James Harris
If the KBC is sent a command which it doesn't recognise what does it do?
Ignores it.
0597, 05A1

Detection by timeout.
Post by James Harris
As the KBC is not multitasking what happens if the host sends it a
command while it is in the middle of receiving a byte from the keyboard?
KBC continues to receive the character or it times out. Host must wait.
03AE

Unlike other routines doesn't interrupt itself on byte from host.
This is good as byte will not be lost. However, host may see a delay.
Need to factor in to timeout on writing.
Post by James Harris
If the KBC gets a parity error when receiving a byte from the keyboard
what does it do?
Sends FE to the keyboard to ask it to retry.
0159, 0160
Post by James Harris
What does the KBC do if it detects a failure when sending a byte to the
keyboard?
Doesn't retry by itself but sends FE to the host.
0228
Post by James Harris
We know that when the KBC receives a byte from the keyboard it signals
an interrupt on IRQ1 but is an interrupt generated when the KBC itself
has something to send the host, perhaps in response to a command?
Yes. 8042 hardware sets status bit0 whenever 8042 firmware writes a byte
to the output buffer.
03D3 (esp comment prior)





Any surprises in there? A number of them surprised me and it was good to
finally get an answer to certain queries.

Naturally, the above are interpretations and may be incorrect. Further,
they relate to just one piece of firmware. Later incarnations would
vary. Nevertheless, the above still gives some idea of how all KBCs can
be expected to react.
--
James Harris
Continue reading on narkive:
Loading...