mrubyでPS/2キーボード

処理のプロトタイプを作ってみました。

```ruby
MSPADDR = 0x4a

SETLED = 0
GETKEY = 1

t = BsdIic.new(0)

# Lock Off
t.write(MSPADDR, SETLED, 0)

numlock = 0
capslock = 0

shift = 0

usleep 100_000

char = {0x1c => 'A', 0x32 => 'B', 0x21 => 'C', 0x3a => 'M', 0x70 => '0'}

loop do
  cur = t.read(MSPADDR, 2, GETKEY)
  if cur != nil && cur[0] != 0
    if cur[1] == 0 then
      if cur[0] == 0x77
        numlock = numlock == 0 ? 1 : 0
        t.write(MSPADDR, SETLED, (numlock << 1) | (capslock << 2))
      elsif cur[0] == 0x58
        capslock = capslock == 0 ? 1 : 0
        t.write(MSPADDR, SETLED, (numlock << 1) | (capslock << 2))
      elsif cur[0] == 0x12
        shift = 1
      else
        if shift == 0 && capslock == 0 && numlock != 1
          print (char[cur[0]].ord + 0x20).chr
        else
          print char[cur[0]]
        end
      end
    else
      if cur[0] == 0x12
        shift = 0
      end
    end
  end
  usleep 10_000
end
```

JIS配列のキーボードで文字が入力できました。

```
aAAAAAAAaaaAAaaaammm0000mmmmmMM
```

ちょっと自作キーボード風です。

二版

```ruby
MSPADDR = 0x4a

SETLED = 0
GETKEY = 1

t = BsdIic.new(0)

# Lock Off
t.write(MSPADDR, SETLED, 0)

numlock = 0
capslock = 0

shift = 0

usleep 100_000

char = {0x16 => '1', 0x1e => '2', 0x26 => '3', 0x25 => '4', 0x2e => '5',
0x36 => '6', 0x3d => '7', 0x3e => '8', 0x46 => '9', 0x45 => '0',
0x4c => ';', 0x52 => ':', 0x41 => ',', 0x49 => '.', 0x4a => '/',
0x55 => '^', 0x6a => '\\', 0x54 => '@', 0x5b => '[', 0x5d => ']',
0x54 => '@', 0x1c => 'a', 0x32 => 'b', 0x21 => 'c', 0x23 => 'd', 0x24 => 'e',
0x2b => 'f', 0x34 => 'g', 0x33 => 'h', 0x43 => 'i', 0x3b => 'j', 0x42 => 'k',
0x4B => 'l', 0x3a => 'm', 0x31 => 'n', 0x44 => 'o', 0x4d => 'p', 0x15 => 'q',
0x2d => 'r', 0x1b => 's', 0x2c => 't', 0x3c => 'u', 0x2a => 'v', 0x1d => 'w',
0x22 => 'x', 0x35 => 'y', 0x1a => 'z',
0x70 => '0', 0x69 => '1', 0x72 => '2', 0x7a => '3', 0x6b => '4', 0x73 => '5',
0x74 => '6', 0x6c => '7', 0x75 => '8', 0x7d => '9',
0x71 => '.', 0x4a => '/', 0x7c => '*', 0x7b => '-', 0x79 => '+'}

loop do
  cur = t.read(MSPADDR, 2, GETKEY)
  if cur != nil && cur[0] != 0
    if cur[1] == 0 then
      if cur[0] == 0x77
        numlock = numlock == 0 ? 1 : 0
        t.write(MSPADDR, SETLED, (numlock << 1) | (capslock << 2))
      elsif cur[0] == 0x58
        capslock = capslock == 0 ? 1 : 0
        t.write(MSPADDR, SETLED, (numlock << 1) | (capslock << 2))
      elsif cur[0] == 0x12
        shift |= 1
      elsif cur[0] == 0x59
        shift |= 2
      elsif cur[0] == 0x5a
          print "\n"
      elsif cur[0] == 0x29
          print ' '
      else
        if (shift == 0 && capslock == 0) || numlock == 1
          print char[cur[0]]
        else
          ch = char[cur[0]].ord
          if ch < 0x30
            print (ch + 0x10).chr
          elsif ch < 0x40
            print (ch - 0x10).chr
          elsif ch < 0x60
            print (ch + 0x20).chr
          else
            print (ch - 0x20).chr
          end
        end
#        print cur[0].to_s(16) + "\n"
      end
    else
      if cur[0] == 0x12
        shift &= ~1
      elsif cur[0] == 0x59
        shift &= ~2
      end
#      print cur[0].to_s(16) + " " + cur[1].to_s(16) + "\n"
    end
  end
  usleep 10_000
end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/feb221f6-d26a-497f-a406-5aa07fab7636.png)

Rubocop + 編集版

```ruby
MSPADDR = 0x4a

SETLED = 0
GETKEY = 1

t = BsdIic.new(0)

# Lock Off
t.write(MSPADDR, SETLED, 0)

numlock = false
capslock = false

shift = 0

usleep 100_000

char = { 0x16 => '1', 0x1e => '2', 0x26 => '3', 0x25 => '4', 0x2e => '5',
         0x36 => '6', 0x3d => '7', 0x3e => '8', 0x46 => '9', 0x45 => '0',
         0x4c => ';', 0x52 => ':', 0x41 => ',', 0x49 => '.',
         0x55 => '^', 0x6a => '\\', 0x5b => '[', 0x5d => ']',
         0x54 => '@', 0x1c => 'a', 0x32 => 'b', 0x21 => 'c', 0x23 => 'd',
         0x24 => 'e', 0x2b => 'f', 0x34 => 'g', 0x33 => 'h', 0x43 => 'i',
         0x3b => 'j', 0x42 => 'k', 0x4B => 'l', 0x3a => 'm', 0x31 => 'n',
         0x44 => 'o', 0x4d => 'p', 0x15 => 'q', 0x2d => 'r', 0x1b => 's',
         0x2c => 't', 0x3c => 'u', 0x2a => 'v', 0x1d => 'w',
         0x22 => 'x', 0x35 => 'y', 0x1a => 'z',
         0x70 => '0', 0x69 => '1', 0x72 => '2', 0x7a => '3', 0x6b => '4',
         0x73 => '5', 0x74 => '6', 0x6c => '7', 0x75 => '8', 0x7d => '9',
         0x71 => '.', 0x4a => '/', 0x7c => '*', 0x7b => '-', 0x79 => '+' }

loop do
  cur = t.read(MSPADDR, 2, GETKEY)
  if !cur.nil? && cur[0] != 0
    if cur[1] == 0
      if cur[0] == 0x77
        numlock = !numlock
        t.write(MSPADDR, SETLED, (numlock ? 2 : 0) | (capslock ? 4 : 0))
      elsif cur[0] == 0x58
        capslock = !capslock
        t.write(MSPADDR, SETLED, (numlock ? 2 : 0) | (capslock ? 4 : 0))
      elsif cur[0] == 0x12
        shift |= 1
      elsif cur[0] == 0x59
        shift |= 2
      elsif cur[0] == 0x5a
        print "\n"
      elsif cur[0] == 0x29
        print ' '
      elsif (shift == 0 && !capslock) || numlock
        print char[cur[0]]
      else
        ch = char[cur[0]].ord
        if ch < 0x30
          print (ch + 0x10).chr
        elsif ch < 0x40
          print (ch - 0x10).chr
        elsif ch < 0x60
          print (ch + 0x20).chr
        else
          print (ch - 0x20).chr
        end
        # print cur[0].to_s(16) + "\n"
      end
    elsif cur[0] == 0x12
      shift &= ~1
    elsif cur[0] == 0x59
      shift &= ~2
      # print cur[0].to_s(16) + " " + cur[1].to_s(16) + "\n"
    end
  end
  usleep 10_000
end
```

lockの処理が間違ってるかも。