2011-12-14 03:13:32 +00:00
/*
2012-05-21 15:14:02 +00:00
Copyright 2011 , 2012 Jun WAKO < wakojun @ gmail . com >
2011-12-14 03:13:32 +00:00
This software is licensed with a Modified BSD License .
All of this is supposed to be Free Software , Open Source , DFSG - free ,
GPL - compatible , and OK to use in both free and proprietary applications .
Additions and corrections to this file are welcome .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in
the documentation and / or other materials provided with the
distribution .
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE .
*/
2012-04-27 16:57:36 +00:00
/* M0110A Support was contributed by skagon@github */
2011-12-14 03:13:32 +00:00
# include <stdbool.h>
# include <avr/io.h>
# include <avr/interrupt.h>
# include <util/delay.h>
# include "m0110.h"
# include "debug.h"
2012-05-14 18:41:07 +00:00
static inline uint8_t raw2scan ( uint8_t raw ) ;
2012-04-27 16:57:36 +00:00
static inline uint8_t inquiry ( void ) ;
static inline uint8_t instant ( void ) ;
2011-12-14 03:13:32 +00:00
static inline void clock_lo ( void ) ;
static inline void clock_hi ( void ) ;
static inline bool clock_in ( void ) ;
static inline void data_lo ( void ) ;
static inline void data_hi ( void ) ;
static inline bool data_in ( void ) ;
static inline uint16_t wait_clock_lo ( uint16_t us ) ;
static inline uint16_t wait_clock_hi ( uint16_t us ) ;
static inline uint16_t wait_data_lo ( uint16_t us ) ;
static inline uint16_t wait_data_hi ( uint16_t us ) ;
static inline void idle ( void ) ;
static inline void request ( void ) ;
2012-04-21 02:07:51 +00:00
# define WAIT_US(stat, us, err) do { \
2011-12-14 03:13:32 +00:00
if ( ! wait_ # # stat ( us ) ) { \
m0110_error = err ; \
goto ERROR ; \
} \
} while ( 0 )
2012-04-21 02:07:51 +00:00
# define WAIT_MS(stat, ms, err) do { \
uint16_t _ms = ms ; \
while ( _ms ) { \
if ( wait_ # # stat ( 1000 ) ) { \
break ; \
} \
_ms - - ; \
} \
if ( _ms = = 0 ) { \
m0110_error = err ; \
goto ERROR ; \
} \
} while ( 0 )
2012-05-21 15:14:02 +00:00
# define KEY(raw) ((raw) & 0x7f)
# define IS_BREAK(raw) (((raw) & 0x80) == 0x80)
2011-12-14 03:13:32 +00:00
uint8_t m0110_error = 0 ;
void m0110_init ( void )
{
idle ( ) ;
2012-04-21 02:07:51 +00:00
_delay_ms ( 1000 ) ;
2011-12-14 03:13:32 +00:00
2013-09-21 06:45:42 +00:00
/* Not needed to initialize in fact.
uint8_t data ;
2012-04-21 02:07:51 +00:00
m0110_send ( M0110_MODEL ) ;
2011-12-14 03:13:32 +00:00
data = m0110_recv ( ) ;
print ( " m0110_init model: " ) ; phex ( data ) ; print ( " \n " ) ;
m0110_send ( M0110_TEST ) ;
data = m0110_recv ( ) ;
print ( " m0110_init test: " ) ; phex ( data ) ; print ( " \n " ) ;
2013-09-21 06:45:42 +00:00
*/
2011-12-14 03:13:32 +00:00
}
uint8_t m0110_send ( uint8_t data )
{
m0110_error = 0 ;
request ( ) ;
2012-04-21 02:07:51 +00:00
WAIT_MS ( clock_lo , 250 , 1 ) ; // keyboard may block long time
2011-12-14 03:13:32 +00:00
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
2012-04-21 02:07:51 +00:00
WAIT_US ( clock_lo , 250 , 3 ) ;
2011-12-14 03:13:32 +00:00
if ( data & bit ) {
data_hi ( ) ;
} else {
data_lo ( ) ;
}
2012-04-21 02:07:51 +00:00
WAIT_US ( clock_hi , 200 , 4 ) ;
2011-12-14 03:13:32 +00:00
}
_delay_us ( 100 ) ; // hold last bit for 80us
idle ( ) ;
return 1 ;
ERROR :
2012-04-21 02:07:51 +00:00
print ( " m0110_send err: " ) ; phex ( m0110_error ) ; print ( " \n " ) ;
_delay_ms ( 500 ) ;
2011-12-14 03:13:32 +00:00
idle ( ) ;
return 0 ;
}
uint8_t m0110_recv ( void )
{
uint8_t data = 0 ;
m0110_error = 0 ;
2012-04-21 02:07:51 +00:00
WAIT_MS ( clock_lo , 250 , 1 ) ; // keyboard may block long time
2011-12-14 03:13:32 +00:00
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
data < < = 1 ;
2012-04-21 02:07:51 +00:00
WAIT_US ( clock_lo , 200 , 2 ) ;
WAIT_US ( clock_hi , 200 , 3 ) ;
2011-12-14 03:13:32 +00:00
if ( data_in ( ) ) {
data | = 1 ;
}
}
idle ( ) ;
return data ;
ERROR :
2012-04-21 02:07:51 +00:00
print ( " m0110_recv err: " ) ; phex ( m0110_error ) ; print ( " \n " ) ;
_delay_ms ( 500 ) ;
2011-12-14 03:13:32 +00:00
idle ( ) ;
return 0xFF ;
}
2012-05-21 15:14:02 +00:00
/*
Handling for exceptional case of key combinations for M0110A
Shift and Calc / Arrow key could be operated simultaneously :
Case Shift Arrow Events Interpret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 Down Down 71 , 79 , DD Calc ( d ) * a * b
2 Down Up 71 , 79 , UU Arrow & Calc ( u ) * a
3 Up Down F1 , 79 , DD Shift ( u ) * c
4 Up Up F1 , 79 , UU Shift ( u ) and Arrow & Calc ( u ) * a
Case Shift Calc Events Interpret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5 ( 1 ) Down Down 71 , 71 , 79 , DD Shift ( d ) and Cacl ( d )
6 ( 2 ) Down Up F1 , 71 , 79 , UU Shift ( u ) and Arrow & Calc ( u ) * a
7 ( 1 ) Up Down F1 , 71 , 79 , DD Shift ( u ) and Calc ( d )
8 ( 4 ) Up Up F1 , F1 , 79 , UU Shift ( ux2 ) and Arrow & Calc ( u ) * a
During Calc key is hold :
Case Shift Arrow Events Interpret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A ( 3 ) - - - - Down F1 , 79 , DD Shift ( u ) * c
B - - - - Up 79 , UU Arrow & Calc ( u ) * a
C Down - - - - F1 , 71 Shift ( u ) and Shift ( d )
D Up - - - - F1 Shift ( u )
E Hold Down 79 , DD Normal
F Hold Up 79 , UU Arrow & Calc ( u ) * a
G ( 1 ) Down Down F1 , 71 , 79 , DD Shift ( u ) * b and Calc ( d ) * a
H ( 2 ) Down Up F1 , 71 , 79 , UU Shift ( u ) and Arrow & Calc ( u ) * a
I ( 3 ) Up Down F1 , F1 , 79 , DD Shift ( ux2 ) * c
J ( 4 ) Up Up F1 , 79 , UU Shift ( u ) and Arrow & Calc ( u ) * a
Case Shift Calc Events Interpret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
K ( 1 ) - - - - Down 71 , 79 , DD Calc ( d ) * a
L ( 4 ) - - - - Up F1 , 79 , UU Shift ( u ) and Arrow & Calc ( u ) * a
M ( 1 ) Hold Down 71 , 79 , DD Calc ( d ) * a
N Hold Up 79 , UU Arrow & Calc ( u ) * a
Where DD / UU indicates part of Keypad Down / Up event .
* a : Impossible to distinguish btween Arrow and Calc event .
* b : Shift ( d ) event is ignored .
* c : Arrow / Calc ( d ) event is ignored .
*/
2011-12-14 03:13:32 +00:00
uint8_t m0110_recv_key ( void )
{
2012-04-27 16:57:36 +00:00
static uint8_t keybuf = 0x00 ;
2012-05-21 15:14:02 +00:00
static uint8_t keybuf2 = 0x00 ;
static uint8_t rawbuf = 0x00 ;
uint8_t raw , raw2 , raw3 ;
2012-04-27 16:57:36 +00:00
if ( keybuf ) {
2012-05-21 15:14:02 +00:00
raw = keybuf ;
2012-04-27 16:57:36 +00:00
keybuf = 0x00 ;
2012-05-21 15:14:02 +00:00
return raw ;
2012-04-27 16:57:36 +00:00
}
2012-05-21 15:14:02 +00:00
if ( keybuf2 ) {
raw = keybuf2 ;
keybuf2 = 0x00 ;
return raw ;
}
if ( rawbuf ) {
raw = rawbuf ;
rawbuf = 0x00 ;
} else {
raw = instant ( ) ; // Use INSTANT for better response. Should be INQUIRY ?
}
switch ( KEY ( raw ) ) {
2012-04-27 16:57:36 +00:00
case M0110_KEYPAD :
2012-05-21 15:14:02 +00:00
raw2 = instant ( ) ;
switch ( KEY ( raw2 ) ) {
case M0110_ARROW_UP :
case M0110_ARROW_DOWN :
case M0110_ARROW_LEFT :
case M0110_ARROW_RIGHT :
if ( IS_BREAK ( raw2 ) ) {
// Case B,F,N:
keybuf = ( raw2scan ( raw2 ) | M0110_CALC_OFFSET ) ; // Calc(u)
return ( raw2scan ( raw2 ) | M0110_KEYPAD_OFFSET ) ; // Arrow(u)
}
break ;
}
// Keypad or Arrow
return ( raw2scan ( raw2 ) | M0110_KEYPAD_OFFSET ) ;
2012-04-27 16:57:36 +00:00
break ;
2012-04-28 18:09:40 +00:00
case M0110_SHIFT :
2012-05-21 15:14:02 +00:00
raw2 = instant ( ) ;
switch ( KEY ( raw2 ) ) {
case M0110_SHIFT :
// Case: 5-8,C,G,H
rawbuf = raw2 ;
return raw2scan ( raw ) ; // Shift(d/u)
break ;
case M0110_KEYPAD :
// Shift + Arrow, Calc, or etc.
raw3 = instant ( ) ;
switch ( KEY ( raw3 ) ) {
case M0110_ARROW_UP :
case M0110_ARROW_DOWN :
case M0110_ARROW_LEFT :
case M0110_ARROW_RIGHT :
if ( IS_BREAK ( raw ) ) {
if ( IS_BREAK ( raw3 ) ) {
// Case 4:
print ( " (4) \n " ) ;
keybuf2 = raw2scan ( raw ) ; // Shift(u)
keybuf = ( raw2scan ( raw3 ) | M0110_CALC_OFFSET ) ; // Calc(u)
return ( raw2scan ( raw3 ) | M0110_KEYPAD_OFFSET ) ; // Arrow(u)
} else {
// Case 3:
print ( " (3) \n " ) ;
return ( raw2scan ( raw ) ) ; // Shift(u)
}
} else {
if ( IS_BREAK ( raw3 ) ) {
// Case 2:
print ( " (2) \n " ) ;
keybuf = ( raw2scan ( raw3 ) | M0110_CALC_OFFSET ) ; // Calc(u)
return ( raw2scan ( raw3 ) | M0110_KEYPAD_OFFSET ) ; // Arrow(u)
} else {
// Case 1:
print ( " (1) \n " ) ;
return ( raw2scan ( raw3 ) | M0110_CALC_OFFSET ) ; // Calc(d)
}
}
break ;
default :
// Shift + Keypad
keybuf = ( raw2scan ( raw3 ) | M0110_KEYPAD_OFFSET ) ;
return raw2scan ( raw ) ; // Shift(d/u)
break ;
}
break ;
default :
// Shift + Normal keys
keybuf = raw2scan ( raw2 ) ;
return raw2scan ( raw ) ; // Shift(d/u)
break ;
2012-04-27 16:57:36 +00:00
}
break ;
default :
2012-05-21 15:14:02 +00:00
// Normal keys
return raw2scan ( raw ) ;
2012-04-27 16:57:36 +00:00
break ;
}
}
2012-05-14 18:41:07 +00:00
static inline uint8_t raw2scan ( uint8_t raw ) {
return ( raw = = M0110_NULL ) ? M0110_NULL : (
( raw = = M0110_ERROR ) ? M0110_ERROR : (
( ( raw & 0x80 ) | ( ( raw & 0x7F ) > > 1 ) )
)
) ;
}
2012-04-27 16:57:36 +00:00
static inline uint8_t inquiry ( void )
{
2011-12-14 03:13:32 +00:00
m0110_send ( M0110_INQUIRY ) ;
2012-04-27 16:57:36 +00:00
return m0110_recv ( ) ;
2011-12-14 03:13:32 +00:00
}
2012-04-27 16:57:36 +00:00
static inline uint8_t instant ( void )
{
m0110_send ( M0110_INSTANT ) ;
2012-05-14 18:41:07 +00:00
uint8_t data = m0110_recv ( ) ;
2012-05-21 15:14:02 +00:00
if ( data ! = M0110_NULL ) {
2012-12-03 06:08:23 +00:00
debug_hex ( data ) ; debug ( " " ) ;
2012-05-14 18:41:07 +00:00
}
return data ;
2012-04-27 16:57:36 +00:00
}
2011-12-14 03:13:32 +00:00
static inline void clock_lo ( )
{
M0110_CLOCK_PORT & = ~ ( 1 < < M0110_CLOCK_BIT ) ;
M0110_CLOCK_DDR | = ( 1 < < M0110_CLOCK_BIT ) ;
}
static inline void clock_hi ( )
{
/* input with pull up */
M0110_CLOCK_DDR & = ~ ( 1 < < M0110_CLOCK_BIT ) ;
M0110_CLOCK_PORT | = ( 1 < < M0110_CLOCK_BIT ) ;
}
static inline bool clock_in ( )
{
M0110_CLOCK_DDR & = ~ ( 1 < < M0110_CLOCK_BIT ) ;
M0110_CLOCK_PORT | = ( 1 < < M0110_CLOCK_BIT ) ;
_delay_us ( 1 ) ;
return M0110_CLOCK_PIN & ( 1 < < M0110_CLOCK_BIT ) ;
}
static inline void data_lo ( )
{
M0110_DATA_PORT & = ~ ( 1 < < M0110_DATA_BIT ) ;
M0110_DATA_DDR | = ( 1 < < M0110_DATA_BIT ) ;
}
static inline void data_hi ( )
{
/* input with pull up */
M0110_DATA_DDR & = ~ ( 1 < < M0110_DATA_BIT ) ;
M0110_DATA_PORT | = ( 1 < < M0110_DATA_BIT ) ;
}
static inline bool data_in ( )
{
M0110_DATA_DDR & = ~ ( 1 < < M0110_DATA_BIT ) ;
M0110_DATA_PORT | = ( 1 < < M0110_DATA_BIT ) ;
_delay_us ( 1 ) ;
return M0110_DATA_PIN & ( 1 < < M0110_DATA_BIT ) ;
}
static inline uint16_t wait_clock_lo ( uint16_t us )
{
while ( clock_in ( ) & & us ) { asm ( " " ) ; _delay_us ( 1 ) ; us - - ; }
return us ;
}
static inline uint16_t wait_clock_hi ( uint16_t us )
{
while ( ! clock_in ( ) & & us ) { asm ( " " ) ; _delay_us ( 1 ) ; us - - ; }
return us ;
}
static inline uint16_t wait_data_lo ( uint16_t us )
{
while ( data_in ( ) & & us ) { asm ( " " ) ; _delay_us ( 1 ) ; us - - ; }
return us ;
}
static inline uint16_t wait_data_hi ( uint16_t us )
{
while ( ! data_in ( ) & & us ) { asm ( " " ) ; _delay_us ( 1 ) ; us - - ; }
return us ;
}
static inline void idle ( void )
{
clock_hi ( ) ;
data_hi ( ) ;
}
static inline void request ( void )
{
clock_hi ( ) ;
data_lo ( ) ;
}
2012-05-14 18:41:07 +00:00
/*
Primitive M0110 Library for AVR
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Signaling
- - - - - - - - -
CLOCK is always from KEYBOARD . DATA are sent with MSB first .
1 ) IDLE : both lines are high .
CLOCK ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DATA ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2 ) KEYBOARD - > HOST : HOST reads bit on rising edge .
CLOCK ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DATA ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ X777777X666666X555555X444444X333333X222222X111111X000000X ~ ~ ~ ~ ~ ~ ~
< - - > 160u s ( clock low )
< - - - > 180u s ( clock high )
3 ) HOST - > KEYBOARD : HOST asserts bit on falling edge .
CLOCK ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ | __ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
DATA ~ ~ ~ ~ ~ ~ | _____X777777X666666X555555X444444X333333X222222X111111X000000X ~ ~ ~ ~ ~ ~ ~
< - - - - > 840u s ( request to send by host ) < - - - > 80u s ( hold DATA )
< - - > 180u s ( clock low )
< - - - > 220u s ( clock high )
Protocol
- - - - - - - -
COMMAND :
2012-05-21 15:14:02 +00:00
Inquiry 0x10 get key event with block
2012-05-14 18:41:07 +00:00
Instant 0x12 get key event
Model 0x14 get model number ( M0110 responds with 0x09 )
bit 7 1 if another device connected ( used when keypad exists ? )
bit4 - 6 next device model number
bit1 - 3 keyboard model number
bit 0 always 1
Test 0x16 test ( ACK : 0x7D / NAK : 0x77 )
KEY EVENT :
bit 7 key state ( 0 : press 1 : release )
bit 6 - 1 scan code ( see below )
bit 0 always 1
To get scan code use this : ( ( bits & ( 1 < < 7 ) ) | ( ( bits & 0x7F ) ) > > 1 ) .
2012-05-21 15:14:02 +00:00
Note : On the M0110A , Keypad keys and Arrow keys are preceded by 0x79 .
Moreover , some Keypad keys ( = , / , * and + ) are preceded by 0x71 on press and 0xF1 on release .
2012-05-14 18:41:07 +00:00
ARROW KEYS :
2012-05-21 15:14:02 +00:00
Arrow keys and Calc keys ( + , * , / , = on keypad ) share same byte sequence and preceding byte of
Calc keys ( 0x71 and 0xF1 ) means press and release event of SHIFT . This causes a very confusing situation ,
it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases .
2012-05-14 18:41:07 +00:00
Raw key events :
press release
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Left : 0x79 , 0x0D 0x79 , 0x8D
Right : 0x79 , 0x05 0x79 , 0x85
Up : 0x79 , 0x1B 0x79 , 0x9B
Down : 0x79 , 0x11 0x79 , 0x91
Pad + : 0x71 , 0x79 , 0x0D 0xF1 , 0x79 , 0x8D
Pad * : 0x71 , 0x79 , 0x05 0xF1 , 0x79 , 0x85
Pad / : 0x71 , 0x79 , 0x1B 0xF1 , 0x79 , 0x9B
Pad = : 0x71 , 0x79 , 0x11 0xF1 , 0x79 , 0x91
2012-05-21 15:14:02 +00:00
RAW CODE :
M0110A
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Bcksp | | Clr | = | / | * |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | | | 7 | 8 | 9 | - |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | | - - - - - - - - - - - - - - - |
| CapsLo | A | S | D | F | G | H | J | K | L | ; | ' | Return | | 4 | 5 | 6 | + |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Shift | Z | X | C | V | B | N | M | , | , | / | Shft | Up | | 1 | 2 | 3 | |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | Ent |
| Optio | Mac | Space | \ | Lft | Rgt | Dn | | 0 | . | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| 65 | 25 | 27 | 29 | 2 B | 2F | 2 D | 35 | 39 | 33 | 3 B | 37 | 31 | 67 | | + 0F | * 11 | * 1 B | * 05 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 61 | 19 | 1 B | 1 D | 1F | 23 | 21 | 41 | 45 | 3F | 47 | 43 | 3 D | | | + 33 | + 37 | + 39 | + 1 D |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | | - - - - - - - - - - - - - - - |
| 73 | 01 | 03 | 05 | 07 | 0 B | 09 | 4 D | 51 | 4 B | 53 | 4F | 49 | | + 2 D | + 2F | + 31 | * 0 D |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 71 | 0 D | 0F | 11 | 13 | 17 | 5 B | 5 D | 27 | 5F | 59 | 71 | + 1 B | | + 27 | + 29 | + 2 B | |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | + 19 |
| 75 | 6F | 63 | 55 | + 0 D | + 05 | + 11 | | + 25 | + 03 | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
+ 0x79 , 0xDD / 0xF1 , 0 xUU
* 0x71 , 0x79 , DD / 0xF1 , 0x79 , 0 xUU
MODEL NUMBER :
M0110 : 0x09 00001001 : model number 4 ( 100 )
M0110A : 0x0B 00001011 : model number 5 ( 101 )
M0110 & M0120 : ? ? ?
Scan Code
- - - - - - - - -
m0110_recv_key ( ) function returns following scan codes instead of raw key events .
Scan codes are 1 byte long and MSB ( bit7 ) is set when key is released .
2012-05-14 18:41:07 +00:00
2013-09-25 06:20:21 +00:00
M0110 M0120
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Backs | | Clr | - | Lft | Rgt |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | \ | | 7 | 8 | 9 | Up |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| CapsLo | A | S | D | F | G | H | J | K | L | ; | ' | Return | | 4 | 5 | 6 | Dn |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Shift | Z | X | C | V | B | N | M | , | , | / | | | 1 | 2 | 3 | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | Ent |
| Opt | Mac | Space | Enter | Opt | | 0 | . | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| 32 | 12 | 13 | 14 | 15 | 17 | 16 | 1 A | 1 C | 19 | 1 D | 1 B | 18 | 33 | | 47 | 4 E | 46 | 42 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 30 | 0 C | 0 D | 0 E | 0F | 10 | 11 | 20 | 22 | 1F | 23 | 21 | 1 E | 2 A | | 59 | 5 B | 5 C | 4 D |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 39 | 00 | 01 | 02 | 03 | 05 | 04 | 26 | 28 | 25 | 29 | 27 | 24 | | 56 | 57 | 58 | 48 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 38 | 06 | 07 | 08 | 09 | 0 B | 2 D | 2 E | 2 B | 2F | 2 C | 38 | | 53 | 54 | 55 | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | 4 C |
| 3 A | 37 | 31 | 34 | 3 A | | 52 | 41 | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
2012-05-14 18:41:07 +00:00
M0110A
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | Bcksp | | Clr | = | / | * |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | | | 7 | 8 | 9 | - |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | | - - - - - - - - - - - - - - - |
| CapsLo | A | S | D | F | G | H | J | K | L | ; | ' | Return | | 4 | 5 | 6 | + |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| Shift | Z | X | C | V | B | N | M | , | , | / | Shft | Up | | 1 | 2 | 3 | |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | Ent |
| Optio | Mac | Space | \ | Lft | Rgt | Dn | | 0 | . | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . , - - - - - - - - - - - - - - - .
| 32 | 12 | 13 | 14 | 15 | 17 | 16 | 1 A | 1 C | 19 | 1 D | 1 B | 18 | 33 | | 47 | 68 | 6 D | 62 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 30 | 0 C | 0 D | 0 E | 0F | 10 | 11 | 20 | 22 | 1F | 23 | 21 | 1 E | | | 59 | 5 B | 5 C | 4 E |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | | - - - - - - - - - - - - - - - |
| 39 | 00 | 01 | 02 | 03 | 05 | 04 | 26 | 28 | 25 | 29 | 27 | 24 | | 56 | 57 | 58 | 66 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | - - - - - - - - - - - - - - - |
| 38 | 06 | 07 | 08 | 09 | 0 B | 2 D | 2 E | 2 B | 2F | 2 C | 38 | 4 D | | 53 | 54 | 55 | |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' | - - - - - - - - - - - | 4 C |
| 3 A | 37 | 31 | 2 A | 46 | 42 | 48 | | 52 | 41 | |
` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' ` - - - - - - - - - - - - - - - '
References
- - - - - - - - - -
Technical Info for 128 K / 512 K and Plus
ftp : //ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
ftp : //ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
Protocol :
Page 20 of Tech Info for 128 K / 512 K
http : //www.mac.linux-m68k.org/devel/plushw.php
Connector :
Page 20 of Tech Info for 128 K / 512 K
http : //www.kbdbabel.org/conn/kbd_connector_macplus.png
Signaling :
http : //www.kbdbabel.org/signaling/kbd_signaling_mac.png
http : //typematic.blog.shinobi.jp/Entry/14/
Scan Codes :
Page 22 of Tech Info for 128 K / 512 K
Page 07 of Tech Info for Plus
http : //m0115.web.fc2.com/m0110.jpg
http : //m0115.web.fc2.com/m0110a.jpg
*/