Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Maximilian Friedersdorff 2024-07-04 15:20:50 +01:00
commit caad39421c
170 changed files with 38730 additions and 26170 deletions

View file

@ -17,11 +17,17 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/avr/bootloader.c
# Option modules
ifeq (yes,$(strip $(NO_KEYBOARD)))
OPT_DEFS += -DNO_KEYBOARD
endif
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
SRC += $(COMMON_DIR)/unimap.c
OPT_DEFS += -DUNIMAP_ENABLE
OPT_DEFS += -DACTIONMAP_ENABLE
ifndef KEYMAP_SECTION_ENABLE
KEYMAP_SECTION_ENABLE = yes
endif
else
ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
SRC += $(COMMON_DIR)/actionmap.c
@ -75,6 +81,10 @@ ifeq (yes,$(strip $(NKRO_ENABLE)))
OPT_DEFS += -DNKRO_ENABLE
endif
ifeq (yes,$(strip $(NKRO_6KRO_ENABLE)))
OPT_DEFS += -DNKRO_6KRO_ENABLE
endif
ifeq (yes,$(strip $(USB_6KRO_ENABLE)))
OPT_DEFS += -DUSB_6KRO_ENABLE
endif
@ -98,18 +108,18 @@ ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE)))
OPT_DEFS += -DKEYMAP_SECTION_ENABLE
ifeq ($(strip $(MCU)),atmega32u2)
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr35.x
EXTRALDFLAGS += -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr35.x
else ifeq ($(strip $(MCU)),atmega32u4)
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
EXTRALDFLAGS += -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
else ifeq ($(strip $(MCU)),at90usb1286)
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr51.x
EXTRALDFLAGS += -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr51.x
else
EXTRALDFLAGS = $(error no ldscript for keymap section)
EXTRALDFLAGS += $(error no ldscript for keymap section)
endif
endif
# Version string
TMK_VERSION := $(shell (git describe --always --dirty=+ || echo 'unknown') 2> /dev/null)
TMK_VERSION := $(shell (git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
OPT_DEFS += -DTMK_VERSION=$(TMK_VERSION)

View file

@ -449,6 +449,17 @@ void register_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(KEYCODE2CONSUMER(code));
}
else if (code == KC_BOOTLOADER) {
clear_keyboard();
wait_ms(50);
bootloader_jump();
}
#ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY(code) {
mousekey_on(code);
mousekey_send();
}
#endif
}
void unregister_code(uint8_t code)
@ -498,6 +509,12 @@ void unregister_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(0);
}
#ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY(code) {
mousekey_off(code);
mousekey_send();
}
#endif
}
void type_code(uint8_t code)

View file

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "keycode.h"
#include "action_code.h"
#include "action_layer.h"
#include "action_macro.h"

View file

@ -229,7 +229,6 @@ enum usage_pages {
};
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM<<10 | (id))
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER<<10 | (id))
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
@ -269,7 +268,7 @@ enum layer_pram_tap_op {
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xc0 | ((mods>>8)&0x1f))
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xc0 | (((mods)>>8)&0x1f))
/* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)

View file

@ -142,6 +142,108 @@ static uint8_t current_layer_for_key(keypos_t key)
}
#ifdef BOOTMAGIC_ENABLE
#include "keymap.h"
extern keymap_config_t keymap_config;
static uint8_t config_keymap(uint8_t keycode)
{
switch (keycode) {
case KC_CAPSLOCK:
case KC_LOCKING_CAPS:
if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
return KC_LCTL;
}
return keycode;
case KC_LCTL:
if (keymap_config.swap_control_capslock) {
return KC_CAPSLOCK;
}
return KC_LCTL;
case KC_LALT:
if (keymap_config.swap_lalt_lgui) {
if (keymap_config.no_gui) {
return KC_NO;
}
return KC_LGUI;
}
return KC_LALT;
case KC_LGUI:
if (keymap_config.swap_lalt_lgui) {
return KC_LALT;
}
if (keymap_config.no_gui) {
return KC_NO;
}
return KC_LGUI;
case KC_RALT:
if (keymap_config.swap_ralt_rgui) {
if (keymap_config.no_gui) {
return KC_NO;
}
return KC_RGUI;
}
return KC_RALT;
case KC_RGUI:
if (keymap_config.swap_ralt_rgui) {
return KC_RALT;
}
if (keymap_config.no_gui) {
return KC_NO;
}
return KC_RGUI;
case KC_GRAVE:
if (keymap_config.swap_grave_esc) {
return KC_ESC;
}
return KC_GRAVE;
case KC_ESC:
if (keymap_config.swap_grave_esc) {
return KC_GRAVE;
}
return KC_ESC;
case KC_BSLASH:
if (keymap_config.swap_backslash_backspace) {
return KC_BSPACE;
}
return KC_BSLASH;
case KC_BSPACE:
if (keymap_config.swap_backslash_backspace) {
return KC_BSLASH;
}
return KC_BSPACE;
default:
return keycode;
}
}
static action_t get_action(uint8_t layer, keypos_t key)
{
action_t act = action_for_key(layer, key);
switch (act.kind.id) {
case ACT_LMODS:
case ACT_RMODS:
case ACT_LMODS_TAP:
case ACT_RMODS_TAP:
act.key.code = config_keymap(act.key.code);
break;
case ACT_LAYER_TAP:
case ACT_LAYER_TAP_EXT:
act.layer_tap.code = config_keymap(act.layer_tap.code);
break;
default:
break;
}
return act;
}
#else
static action_t get_action(uint8_t layer, keypos_t key)
{
return action_for_key(layer, key);
}
#endif
#ifndef NO_TRACK_KEY_PRESS
/* record layer on where key is pressed */
static uint8_t layer_pressed[MATRIX_ROWS][MATRIX_COLS] = {};
@ -161,5 +263,5 @@ action_t layer_switch_get_action(keyevent_t event)
#else
layer = current_layer_for_key(event.key);
#endif
return action_for_key(layer, event.key);
return get_action(layer, event.key);
}

View file

@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
static inline void add_key_byte(uint8_t code);
static inline void del_key_byte(uint8_t code);
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
static inline void add_key_bit(uint8_t code);
static inline void del_key_bit(uint8_t code);
#endif
@ -75,7 +75,7 @@ void send_keyboard_report(void) {
/* key */
void add_key(uint8_t key)
{
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
if (keyboard_protocol && keyboard_nkro) {
add_key_bit(key);
return;
@ -86,7 +86,7 @@ void add_key(uint8_t key)
void del_key(uint8_t key)
{
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
if (keyboard_protocol && keyboard_nkro) {
del_key_bit(key);
return;
@ -159,7 +159,7 @@ uint8_t has_anymod(void)
uint8_t get_first_key(void)
{
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
if (keyboard_protocol && keyboard_nkro) {
uint8_t i = 0;
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
@ -286,7 +286,7 @@ static inline void del_key_byte(uint8_t code)
#endif
}
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
static inline void add_key_bit(uint8_t code)
{
if ((code>>3) < KEYBOARD_REPORT_BITS) {

View file

@ -271,7 +271,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_MEDIA_REWIND ACTION_USAGE_CONSUMER(TRANSPORT_REWIND)
#define AC_MEDIA_STOP ACTION_USAGE_CONSUMER(TRANSPORT_STOP)
#define AC_MEDIA_PLAY_PAUSE ACTION_USAGE_CONSUMER(TRANSPORT_PLAY_PAUSE)
#define AC_MEDIA_EJECT ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
#define AC_MEDIA_EJECT ACTION_USAGE_CONSUMER(TRANSPORT_EJECT)
#define AC_MEDIA_SELECT ACTION_USAGE_CONSUMER(APPLAUNCH_CC_CONFIG)
#define AC_MAIL ACTION_USAGE_CONSUMER(APPLAUNCH_EMAIL)
#define AC_CALCULATOR ACTION_USAGE_CONSUMER(APPLAUNCH_CALCULATOR)
@ -285,24 +285,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_WWW_FAVORITES ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
#define AC_BRIGHTNESS_INC ACTION_USAGE_CONSUMER(BRIGHTNESS_INCREMENT)
#define AC_BRIGHTNESS_DEC ACTION_USAGE_CONSUMER(BRIGHTNESS_DECREMENT)
#define AC_MEDIA_STOP_EJECT ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
/* Mousekey */
#define AC_MS_UP ACTION_MOUSEKEY(KC_MS_UP)
#define AC_MS_DOWN ACTION_MOUSEKEY(KC_MS_DOWN)
#define AC_MS_LEFT ACTION_MOUSEKEY(KC_MS_LEFT)
#define AC_MS_RIGHT ACTION_MOUSEKEY(KC_MS_RIGHT)
#define AC_MS_BTN1 ACTION_MOUSEKEY(KC_MS_BTN1)
#define AC_MS_BTN2 ACTION_MOUSEKEY(KC_MS_BTN2)
#define AC_MS_BTN3 ACTION_MOUSEKEY(KC_MS_BTN3)
#define AC_MS_BTN4 ACTION_MOUSEKEY(KC_MS_BTN4)
#define AC_MS_BTN5 ACTION_MOUSEKEY(KC_MS_BTN5)
#define AC_MS_WH_UP ACTION_MOUSEKEY(KC_MS_WH_UP)
#define AC_MS_WH_DOWN ACTION_MOUSEKEY(KC_MS_WH_DOWN)
#define AC_MS_WH_LEFT ACTION_MOUSEKEY(KC_MS_WH_LEFT)
#define AC_MS_WH_RIGHT ACTION_MOUSEKEY(KC_MS_WH_RIGHT)
#define AC_MS_ACCEL0 ACTION_MOUSEKEY(KC_MS_ACCEL0)
#define AC_MS_ACCEL1 ACTION_MOUSEKEY(KC_MS_ACCEL1)
#define AC_MS_ACCEL2 ACTION_MOUSEKEY(KC_MS_ACCEL2)
#define AC_MS_UP ACTION_KEY(KC_MS_UP)
#define AC_MS_DOWN ACTION_KEY(KC_MS_DOWN)
#define AC_MS_LEFT ACTION_KEY(KC_MS_LEFT)
#define AC_MS_RIGHT ACTION_KEY(KC_MS_RIGHT)
#define AC_MS_BTN1 ACTION_KEY(KC_MS_BTN1)
#define AC_MS_BTN2 ACTION_KEY(KC_MS_BTN2)
#define AC_MS_BTN3 ACTION_KEY(KC_MS_BTN3)
#define AC_MS_BTN4 ACTION_KEY(KC_MS_BTN4)
#define AC_MS_BTN5 ACTION_KEY(KC_MS_BTN5)
#define AC_MS_WH_UP ACTION_KEY(KC_MS_WH_UP)
#define AC_MS_WH_DOWN ACTION_KEY(KC_MS_WH_DOWN)
#define AC_MS_WH_LEFT ACTION_KEY(KC_MS_WH_LEFT)
#define AC_MS_WH_RIGHT ACTION_KEY(KC_MS_WH_RIGHT)
#define AC_MS_ACCEL0 ACTION_KEY(KC_MS_ACCEL0)
#define AC_MS_ACCEL1 ACTION_KEY(KC_MS_ACCEL1)
#define AC_MS_ACCEL2 ACTION_KEY(KC_MS_ACCEL2)
/* Command */
#define AC_BOOTLOADER ACTION_COMMAND(COMMAND_BOOTLOADER, 0)
@ -353,8 +354,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_RO ACTION_KEY(KC_INT1)
#define AC_KANA ACTION_KEY(KC_INT2)
#define AC_JYEN ACTION_KEY(KC_INT3)
#define AC_JPY ACTION_KEY(KC_INT3)
#define AC_HENK ACTION_KEY(KC_INT4)
#define AC_MHEN ACTION_KEY(KC_INT5)
#define AC_MACJ ACTION_KEY(KC_LANG1)
#define AC_MACE ACTION_KEY(KC_LANG2)
/* Korean specific */
#define AC_HAEN ACTION_KEY(KC_LANG1)
#define AC_HANJ ACTION_KEY(KC_LANG2)
/* Keypad */
#define AC_P1 ACTION_KEY(KC_KP_1)
#define AC_P2 ACTION_KEY(KC_KP_2)
@ -376,23 +383,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_PPLS ACTION_KEY(KC_KP_PLUS)
#define AC_PEQL ACTION_KEY(KC_KP_EQUAL)
#define AC_PENT ACTION_KEY(KC_KP_ENTER)
/* Unix function key */
#define AC_EXEC ACTION_KEY(KC_EXECUTE)
#define AC_SLCT ACTION_KEY(KC_SELECT)
#define AC_AGIN ACTION_KEY(KC_AGAIN)
#define AC_PSTE ACTION_KEY(KC_PASTE)
/* Mousekey */
#define AC_MS_U ACTION_MOUSEKEY(KC_MS_UP)
#define AC_MS_D ACTION_MOUSEKEY(KC_MS_DOWN)
#define AC_MS_L ACTION_MOUSEKEY(KC_MS_LEFT)
#define AC_MS_R ACTION_MOUSEKEY(KC_MS_RIGHT)
#define AC_BTN1 ACTION_MOUSEKEY(KC_MS_BTN1)
#define AC_BTN2 ACTION_MOUSEKEY(KC_MS_BTN2)
#define AC_BTN3 ACTION_MOUSEKEY(KC_MS_BTN3)
#define AC_BTN4 ACTION_MOUSEKEY(KC_MS_BTN4)
#define AC_BTN5 ACTION_MOUSEKEY(KC_MS_BTN5)
#define AC_WH_U ACTION_MOUSEKEY(KC_MS_WH_UP)
#define AC_WH_D ACTION_MOUSEKEY(KC_MS_WH_DOWN)
#define AC_WH_L ACTION_MOUSEKEY(KC_MS_WH_LEFT)
#define AC_WH_R ACTION_MOUSEKEY(KC_MS_WH_RIGHT)
#define AC_ACL0 ACTION_MOUSEKEY(KC_MS_ACCEL0)
#define AC_ACL1 ACTION_MOUSEKEY(KC_MS_ACCEL1)
#define AC_ACL2 ACTION_MOUSEKEY(KC_MS_ACCEL2)
#define AC_MS_U ACTION_KEY(KC_MS_UP)
#define AC_MS_D ACTION_KEY(KC_MS_DOWN)
#define AC_MS_L ACTION_KEY(KC_MS_LEFT)
#define AC_MS_R ACTION_KEY(KC_MS_RIGHT)
#define AC_BTN1 ACTION_KEY(KC_MS_BTN1)
#define AC_BTN2 ACTION_KEY(KC_MS_BTN2)
#define AC_BTN3 ACTION_KEY(KC_MS_BTN3)
#define AC_BTN4 ACTION_KEY(KC_MS_BTN4)
#define AC_BTN5 ACTION_KEY(KC_MS_BTN5)
#define AC_WH_U ACTION_KEY(KC_MS_WH_UP)
#define AC_WH_D ACTION_KEY(KC_MS_WH_DOWN)
#define AC_WH_L ACTION_KEY(KC_MS_WH_LEFT)
#define AC_WH_R ACTION_KEY(KC_MS_WH_RIGHT)
#define AC_ACL0 ACTION_KEY(KC_MS_ACCEL0)
#define AC_ACL1 ACTION_KEY(KC_MS_ACCEL1)
#define AC_ACL2 ACTION_KEY(KC_MS_ACCEL2)
/* Sytem Control */
#define AC_PWR ACTION_USAGE_SYSTEM(SYSTEM_POWER_DOWN)
#define AC_SLEP ACTION_USAGE_SYSTEM(SYSTEM_SLEEP)
@ -407,7 +419,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_MRWD ACTION_USAGE_CONSUMER(TRANSPORT_REWIND)
#define AC_MSTP ACTION_USAGE_CONSUMER(TRANSPORT_STOP)
#define AC_MPLY ACTION_USAGE_CONSUMER(TRANSPORT_PLAY_PAUSE)
#define AC_EJCT ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
#define AC_EJCT ACTION_USAGE_CONSUMER(TRANSPORT_EJECT)
#define AC_MSEL ACTION_USAGE_CONSUMER(APPLAUNCH_CC_CONFIG)
#define AC_MAIL ACTION_USAGE_CONSUMER(APPLAUNCH_EMAIL)
#define AC_CALC ACTION_USAGE_CONSUMER(APPLAUNCH_CALCULATOR)
@ -421,6 +433,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AC_WFAV ACTION_USAGE_CONSUMER(APPCONTROL_BOOKMARKS)
#define AC_BRTI ACTION_USAGE_CONSUMER(BRIGHTNESS_INCREMENT)
#define AC_BRTD ACTION_USAGE_CONSUMER(BRIGHTNESS_DECREMENT)
#define AC_STEJ ACTION_USAGE_CONSUMER(TRANSPORT_STOP_EJECT)
/* Transparent */
#define AC_TRNS ACTION_KEY(KC_TRANSPARENT)

View file

@ -2,6 +2,8 @@
#include <stdbool.h>
#include <avr/eeprom.h>
#include "eeconfig.h"
#include "keymap.h"
#include "print.h"
void eeconfig_init(void)
{
@ -22,7 +24,12 @@ void eeconfig_enable(void)
void eeconfig_disable(void)
{
eeprom_write_word(EECONFIG_MAGIC, 0xFFFF);
eeprom_write_word(EECONFIG_MAGIC, 0xFFFF);
eeprom_write_byte(EECONFIG_DEBUG, 0xFF);
eeprom_write_byte(EECONFIG_DEFAULT_LAYER, 0xFF);
eeprom_write_byte(EECONFIG_KEYMAP, 0xFF);
eeprom_write_byte(EECONFIG_MOUSEKEY_ACCEL, 0xFF);
eeprom_write_byte(EECONFIG_BACKLIGHT, 0xFF);
}
bool eeconfig_is_enabled(void)
@ -43,3 +50,13 @@ void eeconfig_write_keymap(uint8_t val) { eeprom_write_byte(EECONFIG_KEYMAP, val
uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
void eeconfig_write_backlight(uint8_t val) { eeprom_write_byte(EECONFIG_BACKLIGHT, val); }
#endif
void eeconfig_debug(void)
{
xprintf("eeprom:");
for (int i = 0; i < 16 /* E2END + 1 */; i++) {
if ((i % 16) == 0) { xprintf("\n%04X: ", i); }
xprintf("%02X ", eeprom_read_byte((uint8_t *)i));
}
xprintf("\n");
}

View file

@ -115,21 +115,25 @@ void suspend_power_down(void)
bool suspend_wakeup_condition(void)
{
#ifndef NO_KEYBOARD
matrix_power_up();
matrix_scan();
matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
#endif
return false;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
#ifndef NO_KEYBOARD
// clear keyboard state
matrix_clear();
clear_keyboard();
#endif
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif

View file

@ -34,7 +34,7 @@ void bootmagic(void)
/* eeconfig clear */
if (bootmagic_scan_key(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
eeconfig_init();
eeconfig_disable();
}
/* bootloader */
@ -45,6 +45,10 @@ void bootmagic(void)
/* user-defined checks */
hook_bootmagic();
if (!eeconfig_is_enabled()) {
goto WAIT;
}
/* debug enable */
debug_config.raw = eeconfig_read_debug();
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
@ -61,35 +65,38 @@ void bootmagic(void)
eeconfig_write_debug(debug_config.raw);
/* keymap config */
keymap_config.raw = eeconfig_read_keymap();
keymap_config_t kc;
kc.raw = eeconfig_read_keymap();
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
kc.swap_control_capslock = !kc.swap_control_capslock;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
keymap_config.capslock_to_control = !keymap_config.capslock_to_control;
kc.capslock_to_control = !kc.capslock_to_control;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
kc.swap_lalt_lgui = !kc.swap_lalt_lgui;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
kc.swap_ralt_rgui = !kc.swap_ralt_rgui;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_NO_GUI)) {
keymap_config.no_gui = !keymap_config.no_gui;
kc.no_gui = !kc.no_gui;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc;
kc.swap_grave_esc = !kc.swap_grave_esc;
}
if (bootmagic_scan_key(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace;
kc.swap_backslash_backspace = !kc.swap_backslash_backspace;
}
if (bootmagic_scan_key(BOOTMAGIC_HOST_NKRO)) {
keymap_config.nkro = !keymap_config.nkro;
kc.nkro = !kc.nkro;
}
eeconfig_write_keymap(keymap_config.raw);
eeconfig_write_keymap(kc.raw);
#ifdef NKRO_ENABLE
keyboard_nkro = keymap_config.nkro;
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
if (kc.nkro) {
keyboard_nkro = !keyboard_nkro;
}
#endif
/* default layer */
@ -109,6 +116,18 @@ void bootmagic(void)
default_layer = eeconfig_read_default_layer();
default_layer_set((uint32_t)default_layer);
}
keymap_config = kc;
// wait until all key is released
WAIT:
matrix_scan();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) {
goto WAIT;
wait_ms(10);
}
}
}
static bool scan_key(uint16_t code)

View file

@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wait.h"
#include "keycode.h"
#include "host.h"
#include "keymap.h"
#include "print.h"
#include "debug.h"
#include "util.h"
@ -134,7 +133,7 @@ static void command_common_help(void)
"e: eeprom\n"
#endif
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
"n: NKRO\n"
#endif
@ -145,6 +144,9 @@ static void command_common_help(void)
}
#ifdef BOOTMAGIC_ENABLE
#include "keymap.h"
__attribute__ ((weak)) void eeconfig_debug(void) {}
static void print_eeconfig(void)
{
print("default_layer: "); print_dec(eeconfig_read_default_layer()); print("\n");
@ -176,6 +178,8 @@ static void print_eeconfig(void)
print(".enable: "); print_dec(bc.enable); print("\n");
print(".level: "); print_dec(bc.level); print("\n");
#endif
eeconfig_debug();
}
#endif
@ -314,7 +318,7 @@ static bool command_common(uint8_t code)
#ifdef COMMAND_ENABLE
" COMMAND"
#endif
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
" NKRO"
#endif
#ifdef KEYMAP_SECTION_ENABLE
@ -336,7 +340,7 @@ static bool command_common(uint8_t code)
print_val_hex8(host_keyboard_leds());
print_val_hex8(keyboard_protocol);
print_val_hex8(keyboard_idle);
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
print_val_hex8(keyboard_nkro);
#endif
print_val_hex32(timer_read32());
@ -355,7 +359,7 @@ static bool command_common(uint8_t code)
# endif
#endif
break;
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
case KC_N:
clear_keyboard(); //Prevents stuck keys.
keyboard_nkro = !keyboard_nkro;

View file

@ -72,4 +72,6 @@ uint8_t eeconfig_read_backlight(void);
void eeconfig_write_backlight(uint8_t val);
#endif
void eeconfig_debug(void);
#endif

View file

@ -22,6 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Definitions of default hooks
* ------------------------------------------------- */
__attribute__((weak))
void hook_main_loop(void) {}
__attribute__((weak))
void hook_keyboard_loop(void) {}

View file

@ -56,6 +56,10 @@ void hook_usb_wakeup(void);
/* Default behaviour: do nothing. */
void hook_usb_startup_wait_loop(void);
/* Called periodically from main loop */
/* Default behaviour: do nothing. */
void hook_main_loop(void);
/* -------------------------------------
* Keyboard hooks

View file

@ -22,8 +22,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util.h"
#include "debug.h"
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
#endif
#ifdef PS2_MOUSE_ENABLE
# include "ps2_mouse.h"
#endif
#ifdef SERIAL_MOUSE_ENABLE
# include "serial_mouse.h"
#endif
#ifdef ADB_MOUSE_ENABLE
# include "adb.h"
#endif
#ifdef IBMPC_MOUSE_ENABLE
uint8_t ibmpc_mouse_buttons(void);
#endif
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
bool keyboard_nkro = true;
#endif
@ -65,7 +81,35 @@ void host_keyboard_send(report_keyboard_t *report)
void host_mouse_send(report_mouse_t *report)
{
if (!driver) return;
#ifdef MOUSE_EXT_REPORT
// clip and copy to Boot protocol XY
report->boot_x = (report->x > 127) ? 127 : ((report->x < -127) ? -127 : report->x);
report->boot_y = (report->y > 127) ? 127 : ((report->y < -127) ? -127 : report->y);
#endif
/* Mouse buttons integration */
uint8_t b = report->buttons;
#ifdef MOUSEKEY_ENABLE
report->buttons |= mousekey_buttons();
#endif
#ifdef PS2_MOUSE_ENABLE
report->buttons |= ps2_mouse_buttons();
#endif
#ifdef SERIAL_MOUSE_ENABLE
report->buttons |= serial_mouse_buttons();
#endif
#ifdef ADB_MOUSE_ENABLE
report->buttons |= adb_mouse_buttons();
#endif
#ifdef IBMPC_MOUSE_ENABLE
report->buttons |= ibmpc_mouse_buttons();
#endif
(*driver->send_mouse)(report);
report->buttons = b;
if (debug_mouse) {
xprintf("mouse: [%02X|%d %d %d %d]\n", report->buttons, report->x, report->y, report->v, report->h);
}
}
void host_system_send(uint16_t report)

View file

@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern "C" {
#endif
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
extern bool keyboard_nkro;
#endif

View file

@ -103,6 +103,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_JPY KC_INT3
#define KC_HENK KC_INT4
#define KC_MHEN KC_INT5
#define KC_MACJ KC_LANG1
#define KC_MACE KC_LANG2
/* Korean specific */
#define KC_HAEN KC_LANG1
#define KC_HANJ KC_LANG2

View file

@ -27,10 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <avr/pgmspace.h>
#endif
#ifdef BOOTMAGIC_ENABLE
extern keymap_config_t keymap_config;
#endif
static action_t keycode_to_action(uint8_t keycode);
@ -42,71 +38,6 @@ action_t action_for_key(uint8_t layer, keypos_t key)
switch (keycode) {
case KC_FN0 ... KC_FN31:
return keymap_fn_to_action(keycode);
#ifdef BOOTMAGIC_ENABLE
case KC_CAPSLOCK:
case KC_LOCKING_CAPS:
if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
return keycode_to_action(KC_LCTL);
}
return keycode_to_action(keycode);
case KC_LCTL:
if (keymap_config.swap_control_capslock) {
return keycode_to_action(KC_CAPSLOCK);
}
return keycode_to_action(KC_LCTL);
case KC_LALT:
if (keymap_config.swap_lalt_lgui) {
if (keymap_config.no_gui) {
return keycode_to_action(KC_NO);
}
return keycode_to_action(KC_LGUI);
}
return keycode_to_action(KC_LALT);
case KC_LGUI:
if (keymap_config.swap_lalt_lgui) {
return keycode_to_action(KC_LALT);
}
if (keymap_config.no_gui) {
return keycode_to_action(KC_NO);
}
return keycode_to_action(KC_LGUI);
case KC_RALT:
if (keymap_config.swap_ralt_rgui) {
if (keymap_config.no_gui) {
return keycode_to_action(KC_NO);
}
return keycode_to_action(KC_RGUI);
}
return keycode_to_action(KC_RALT);
case KC_RGUI:
if (keymap_config.swap_ralt_rgui) {
return keycode_to_action(KC_RALT);
}
if (keymap_config.no_gui) {
return keycode_to_action(KC_NO);
}
return keycode_to_action(KC_RGUI);
case KC_GRAVE:
if (keymap_config.swap_grave_esc) {
return keycode_to_action(KC_ESC);
}
return keycode_to_action(KC_GRAVE);
case KC_ESC:
if (keymap_config.swap_grave_esc) {
return keycode_to_action(KC_GRAVE);
}
return keycode_to_action(KC_ESC);
case KC_BSLASH:
if (keymap_config.swap_backslash_backspace) {
return keycode_to_action(KC_BSPACE);
}
return keycode_to_action(KC_BSLASH);
case KC_BSPACE:
if (keymap_config.swap_backslash_backspace) {
return keycode_to_action(KC_BSLASH);
}
return keycode_to_action(KC_BSPACE);
#endif
default:
return keycode_to_action(keycode);
}
@ -149,7 +80,7 @@ static action_t keycode_to_action(uint8_t keycode)
return (action_t)ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
break;
case KC_MS_UP ... KC_MS_ACCEL2:
return (action_t)ACTION_MOUSEKEY(keycode);
return (action_t)ACTION_KEY(keycode);
break;
case KC_TRNS:
return (action_t)ACTION_TRANSPARENT;
@ -171,10 +102,6 @@ static action_t keycode_to_action(uint8_t keycode)
* Legacy keymap support
* Consider using new keymap API instead.
*/
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint8_t fn_layer[];
extern const uint8_t fn_keycode[];
__attribute__ ((weak))
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
{
@ -223,10 +150,6 @@ action_t keymap_fn_to_action(uint8_t keycode)
#else
/* user keymaps should be defined somewhere */
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const action_t fn_actions[];
__attribute__ ((weak))
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
{

View file

@ -23,6 +23,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BOOTMAGIC_ENABLE
/* NOTE: Not portable. Bit field order depends on implementation */
typedef union {
@ -40,6 +44,8 @@ typedef union {
} keymap_config_t;
#endif
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const action_t fn_actions[];
/* translates key to keycode */
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
@ -54,6 +60,10 @@ action_t keymap_fn_to_action(uint8_t keycode);
* Legacy keymap
* Consider using new keymap API above instead.
*/
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint8_t fn_layer[];
extern const uint8_t fn_keycode[];
/* keycode of key */
__attribute__ ((deprecated))
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);
@ -65,6 +75,16 @@ uint8_t keymap_fn_layer(uint8_t fn_bits);
/* keycode to send when release Fn key without using */
__attribute__ ((deprecated))
uint8_t keymap_fn_keycode(uint8_t fn_bits);
#else
/* user keymaps should be defined somewhere */
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const action_t fn_actions[];
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -182,6 +182,11 @@ void mousekey_clear(void)
mousekey_accel = 0;
}
uint8_t mousekey_buttons(void)
{
return mouse_report.buttons;
}
static void mousekey_debug(void)
{
if (!debug_mouse) return;

View file

@ -69,6 +69,7 @@ void mousekey_on(uint8_t code);
void mousekey_off(uint8_t code);
void mousekey_clear(void);
void mousekey_send(void);
uint8_t mousekey_buttons(void);
#ifdef __cplusplus
}

View file

@ -30,6 +30,9 @@
#include "util.h"
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
#define xstr(s) str(s)
#define str(s) #s
#ifndef NO_PRINT
@ -100,6 +103,12 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
#else /* NO_PRINT */
#define xprintf(s,...) ((void)0)
#define xsprintf(s,...) ((void)0)
#define xfprintf(s,...) ((void)0)
#define xputs(s) ((void)0)
#define xputc(c) ((void)0)
#define xitoa(v, r, w) ((void)0)
#define xatoi(s, r) ((void)0)
#define print(s) ((void)0)
#define println(s) ((void)0)
#define print_set_sendchar(func) ((void)0)

View file

@ -47,14 +47,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Consumer Page(0x0C)
* https://github.com/tmk/tmk_keyboard/issues/370
*/
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
#define AUDIO_VOL_DOWN 0x00EA
/* Display Brightness Controls https://www.usb.org/sites/default/files/hutrr41_0.pdf */
#define BRIGHTNESS_INCREMENT 0x006F
#define BRIGHTNESS_DECREMENT 0x0070
#define TRANSPORT_FAST_FORWARD 0x00B3
#define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_NEXT_TRACK 0x00B5
#define TRANSPORT_PREV_TRACK 0x00B6
#define TRANSPORT_STOP 0x00B7
#define TRANSPORT_EJECT 0x00B8
#define TRANSPORT_STOP_EJECT 0x00CC
#define TRANSPORT_PLAY_PAUSE 0x00CD
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
#define AUDIO_VOL_DOWN 0x00EA
/* application launch */
#define APPLAUNCH_CC_CONFIG 0x0183
#define APPLAUNCH_EMAIL 0x018A
@ -71,13 +77,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* supplement for Bluegiga iWRAP HID(not supported by Windows?) */
#define APPLAUNCH_LOCK 0x019E
#define TRANSPORT_RECORD 0x00B2
#define TRANSPORT_FAST_FORWARD 0x00B3
#define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_EJECT 0x00B8
#define APPCONTROL_MINIMIZE 0x0206
/* Display Brightness Controls https://www.usb.org/sites/default/files/hutrr41_0.pdf */
#define BRIGHTNESS_INCREMENT 0x006F
#define BRIGHTNESS_DECREMENT 0x0070
/*
* Generic Desktop Page(0x01) - system power control
@ -94,7 +94,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
# define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
#elif defined(PROTOCOL_LUFA) && (defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE))
# include "protocol/lufa/descriptor.h"
# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
@ -142,7 +142,7 @@ typedef union {
uint8_t reserved;
uint8_t keys[KEYBOARD_REPORT_KEYS];
};
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
struct {
uint8_t mods;
uint8_t bits[KEYBOARD_REPORT_BITS];
@ -159,8 +159,15 @@ typedef struct {
typedef struct {
uint8_t buttons;
#ifndef MOUSE_EXT_REPORT
int8_t x;
int8_t y;
#else
int8_t boot_x;
int8_t boot_y;
int16_t x;
int16_t y;
#endif
int8_t v;
int8_t h;
} __attribute__ ((packed)) report_mouse_t;
@ -182,7 +189,7 @@ typedef struct {
(key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \
(key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \
(key == KC_MEDIA_STOP ? TRANSPORT_STOP : \
(key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \
(key == KC_MEDIA_EJECT ? TRANSPORT_EJECT : \
(key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \
(key == KC_MEDIA_SELECT ? APPLAUNCH_CC_CONFIG : \
(key == KC_MAIL ? APPLAUNCH_EMAIL : \

View file

@ -19,6 +19,7 @@ static inline void ringbuf_write(ringbuf_t *buf, uint8_t data);
static inline bool ringbuf_is_empty(ringbuf_t *buf);
static inline bool ringbuf_is_full(ringbuf_t *buf);
static inline void ringbuf_reset(ringbuf_t *buf);
static inline void ringbuf_push(ringbuf_t *buf, uint8_t data);
static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size)
{
@ -70,4 +71,10 @@ static inline void ringbuf_reset(ringbuf_t *buf)
buf->head = 0;
buf->tail = 0;
}
static inline void ringbuf_push(ringbuf_t *buf, uint8_t data)
{
buf->buffer[buf->head] = data;
buf->head++;
buf->head &= buf->size_mask;
}
#endif

View file

@ -264,6 +264,7 @@ enum unimap_position_codes {
#define UNIMAP_NUBS UNIMAP_NONUS_BSLASH
/* Japanese specific */
#define UNIMAP_ZKHK UNIMAP_GRAVE
#define UNIMAP_JPY UNIMAP_JYEN
/* Keypad */
#define UNIMAP_P1 UNIMAP_KP_1
#define UNIMAP_P2 UNIMAP_KP_2

View file

@ -104,6 +104,12 @@ void adb_mouse_task(void) {
}
#endif
static bool adb_srq = false;
bool adb_service_request(void)
{
return adb_srq;
}
// This sends Talk command to read data from register and returns length of the data.
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
{
@ -157,7 +163,8 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
// portion of the stop bit of any command or data transaction. The device must lengthen
// the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
// http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
if (!data_in()) { adb_srq = true; } else { adb_srq = false; }
if (!wait_data_hi(500)) { // wait for end of SRQ:(310us Adjustable Keyboard)
xprintf("R");
sei();
return 0;
@ -191,12 +198,14 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
// |________| |
//
uint8_t lo = (uint8_t) wait_data_hi(130);
if (!lo)
goto error; // no more bit or after stop bit
if (!lo) {
goto error; // SRQ?
}
uint8_t hi = (uint8_t) wait_data_lo(lo);
if (!hi)
goto error; // stop bit extedned by Srq?
if (!hi) {
goto error; // stop bit
}
if (n/8 >= len) continue; // can't store in buf
@ -209,6 +218,7 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
error:
sei();
_delay_us(200);
return n/8;
}
@ -227,7 +237,8 @@ void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
attention();
send_byte((addr<<4) | ADB_CMD_LISTEN | reg);
place_bit0(); // Stopbit(0)
// TODO: Service Request
if (!data_in()) { adb_srq = true; } else { adb_srq = false; }
wait_data_hi(500); // Service Request
_delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1)
for (int8_t i = 0; i < len; i++) {
@ -236,6 +247,7 @@ void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
}
place_bit0(); // Stopbit(0);
sei();
_delay_us(200);
}
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l)
@ -254,13 +266,32 @@ void adb_host_flush(uint8_t addr)
sei();
}
void adb_host_reset(void)
{
cli();
attention();
send_byte(ADB_CMD_RESET);
place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start
sei();
}
void adb_host_reset_hard(void)
{
data_lo();
_delay_us(3000);
data_hi();
}
// send state of LEDs
void adb_host_kbd_led(uint8_t addr, uint8_t led)
{
// Listen Register2
// upper byte: not used
// lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
adb_host_listen(addr, 2, 0, led & 0x07);
uint16_t reg2 = adb_host_talk(addr, 2);
_delay_us(400);
adb_host_listen(addr, 2, reg2 >> 8, (reg2 & 0xF8) | (led & 0x07));
}

View file

@ -68,9 +68,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define ADB_ADDR_13 13
#define ADB_ADDR_14 14
#define ADB_ADDR_15 15
// for temporary purpose, do not use for polling
#define ADB_ADDR_TMP 15
#define ADB_ADDR_MOUSE_POLL 10
// Command Type
#define ADB_CMD_RESET 0
#define ADB_CMD_FLUSH 1
@ -93,6 +90,15 @@ POSSIBILITY OF SUCH DAMAGE.
#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
#define ADB_HANDLER_EXTENDED_MOUSE 0x04
#define ADB_HANDLER_TURBO_MOUSE 0x32
#define ADB_HANDLER_MACALLY2_MOUSE 0x42
#define ADB_HANDLER_MICROSPEED_MACTRAC 0x2F
#define ADB_HANDLER_MICROSPEED_UNKNOWN 0x5F
#define ADB_HANDLER_CONTOUR_MOUSE 0x66
#define ADB_HANDLER_CHPRODUCTS_PRO 0x42
#define ADB_HANDLER_MOUSESYSTEMS_A3 0x03
// pseudo handler
#define ADB_HANDLER_LOGITECH 0x4C
#define ADB_HANDLER_LOGITECH_EXT 0x4D
// ADB host
@ -104,9 +110,13 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
void adb_host_flush(uint8_t addr);
void adb_host_reset(void);
void adb_host_reset_hard(void);
void adb_host_kbd_led(uint8_t addr, uint8_t led);
void adb_mouse_task(void);
void adb_mouse_init(void);
uint8_t adb_mouse_buttons(void);
bool adb_service_request(void);
#endif

View file

@ -42,76 +42,75 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdbool.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
#include "ibmpc.h"
#include "debug.h"
#include "timer.h"
#include "wait.h"
#include "ibmpc.hpp"
#define WAIT(stat, us, err) do { \
if (!wait_##stat(us)) { \
ibmpc_error = err; \
error = err; \
goto ERROR; \
} \
} while (0)
volatile uint16_t ibmpc_isr_debug = 0;
volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_NO;
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
IBMPC IBMPC::interface0 = IBMPC(IBMPC_CLOCK_BIT, IBMPC_DATA_BIT);
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1)
IBMPC IBMPC::interface1 = IBMPC(IBMPC_CLOCK_BIT1, IBMPC_DATA_BIT1);
#endif
/* 2-byte buffer for data received from keyboard
* buffer states:
* FFFF: empty
* FFss: one data
* sstt: two data
* eeFF: error
* where ss, tt and ee are 0x00-0xFE. 0xFF means empty or no data in buffer.
*/
static volatile uint16_t recv_data = 0xFFFF;
/* internal state of receiving data */
static volatile uint16_t isr_state = 0x8000;
static uint8_t timer_start = 0;
void ibmpc_host_init(void)
void IBMPC::host_init(void)
{
// initialize reset pin to HiZ
IBMPC_RST_HIZ();
inhibit();
IBMPC_INT_INIT();
IBMPC_INT_OFF();
int_init();
int_off();
host_isr_clear();
}
void ibmpc_host_enable(void)
void IBMPC::host_enable(void)
{
IBMPC_INT_ON();
int_on();
idle();
}
void ibmpc_host_disable(void)
void IBMPC::host_disable(void)
{
IBMPC_INT_OFF();
int_off();
inhibit();
}
int16_t ibmpc_host_send(uint8_t data)
int16_t IBMPC::host_send(uint8_t data)
{
bool parity = true;
ibmpc_error = IBMPC_ERR_NONE;
error = IBMPC_ERR_NONE;
uint8_t retry = 0;
dprintf("w%02X ", data);
IBMPC_INT_OFF();
// Return when receiving data
//if (isr_state & 0x0FFF) {
if (isr_state != 0x8000) {
dprintf("isr:%04X ", isr_state);
return -1;
}
int_off();
RETRY:
/* terminate a transmission if we have */
inhibit();
wait_us(100); // [5]p.54
wait_us(200); // [5]p.54
/* 'Request to Send' and Start bit */
data_lo();
wait_us(100);
wait_us(200);
clock_hi(); // [5]p.54 [clock low]>100us [5]p.50
WAIT(clock_lo, 10000, 1); // [5]p.53, -10ms [5]p.50
WAIT(clock_lo, 15000, 1); // [5]p.54 T13M, -10ms [5]p.50
/* Data bit[2-9] */
for (uint8_t i = 0; i < 8; i++) {
@ -135,117 +134,89 @@ int16_t ibmpc_host_send(uint8_t data)
/* Stop bit */
wait_us(15);
data_hi();
WAIT(clock_hi, 50, 6);
if (ibmpc_protocol == IBMPC_PROTOCOL_AT_Z150) { goto RECV; }
WAIT(clock_lo, 50, 7);
/* Ack */
WAIT(data_lo, 50, 8);
WAIT(data_lo, 300, 6);
WAIT(data_hi, 300, 7);
WAIT(clock_hi, 300, 8);
/* wait for idle state */
WAIT(clock_hi, 50, 9);
WAIT(data_hi, 50, 10);
#ifdef SIEMENS_PCD_SUPPORT
// inhibit - https://github.com/tmk/tmk_keyboard/issues/747
if (protocol & IBMPC_PROTOCOL_AT) {
wait_us(15);
clock_lo();
wait_us(150);
}
#endif
RECV:
// clear buffer to get response correctly
recv_data = 0xFFFF;
ibmpc_host_isr_clear();
host_isr_clear();
idle();
IBMPC_INT_ON();
return ibmpc_host_recv_response();
int_on();
return host_recv_response();
ERROR:
ibmpc_error |= IBMPC_ERR_SEND;
// Retry for Z-150 AT start bit error
if (error == 1 && retry++ < 10) {
error = IBMPC_ERR_NONE;
dprintf("R ");
goto RETRY;
}
isr_debug = isr_state;
error |= IBMPC_ERR_SEND;
inhibit();
wait_ms(2);
idle();
IBMPC_INT_ON();
int_on();
return -1;
}
/*
* Receive data from keyboard
*/
int16_t ibmpc_host_recv(void)
int16_t IBMPC::host_recv(void)
{
uint16_t data = 0;
uint8_t ret = 0xFF;
int16_t ret = -1;
// Enable ISR if buffer was full
if (ringbuf_is_full()) {
host_isr_clear();
int_on();
idle();
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
data = recv_data;
// remove data from buffer:
// FFFF(empty) -> FFFF
// FFss(one data) -> FFFF
// sstt(two data) -> FFtt
// eeFF(errror) -> FFFF
recv_data = data | (((data&0xFF00) == 0xFF00) ? 0x00FF : 0xFF00);
ret = ringbuf_get();
}
if ((data&0x00FF) == 0x00FF) {
// error: eeFF
switch (data>>8) {
case IBMPC_ERR_FF:
// 0xFF(Overrun/Error) from keyboard
dprintf("!FF! ");
ret = 0xFF;
break;
case IBMPC_ERR_FULL:
// buffer full
dprintf("!FULL! ");
ret = 0xFF;
break;
case 0xFF:
// empty: FFFF
return -1;
default:
// other errors
dprintf("e%02X ", data>>8);
return -1;
}
} else {
if ((data | 0x00FF) != 0xFFFF) {
// two data: sstt
dprintf("b:%04X ", data);
ret = (data>>8);
} else {
// one data: FFss
ret = (data&0x00FF);
}
}
//dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0;
dprintf("r%02X ", ret);
if (ret != -1) dprintf("r%02X ", ret&0xFF);
return ret;
}
int16_t ibmpc_host_recv_response(void)
int16_t IBMPC::host_recv_response(void)
{
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
uint8_t retry = 25;
int16_t data = -1;
while (retry-- && (data = ibmpc_host_recv()) == -1) {
while (retry-- && (data = host_recv()) == -1) {
wait_ms(1);
}
return data;
}
void ibmpc_host_isr_clear(void)
void IBMPC::host_isr_clear(void)
{
ibmpc_isr_debug = 0;
ibmpc_protocol = 0;
ibmpc_error = 0;
isr_debug = 0;
protocol = 0;
error = 0;
isr_state = 0x8000;
recv_data = 0xFFFF;
ringbuf_reset();
}
#define LO8(w) (*((uint8_t *)&(w)))
#define HI8(w) (*(((uint8_t *)&(w))+1))
// NOTE: With this ISR data line can be read within 2us after clock falling edge.
// To read data line early as possible:
// write naked ISR with asembly code to read the line and call C func to do other job?
ISR(IBMPC_INT_VECT)
void IBMPC::isr(void)
{
uint8_t dbit;
dbit = IBMPC_DATA_PIN&(1<<IBMPC_DATA_BIT);
dbit = IBMPC_DATA_PIN&(1<<data_bit);
// Timeout check
uint8_t t;
@ -256,9 +227,9 @@ ISR(IBMPC_INT_VECT)
timer_start = t;
} else {
// This gives 2.0ms at least before timeout
if ((uint8_t)(t - timer_start) >= 3) {
ibmpc_isr_debug = isr_state;
ibmpc_error = IBMPC_ERR_TIMEOUT;
if ((uint8_t)(t - timer_start) >= 5) {
isr_debug = isr_state;
error = IBMPC_ERR_TIMEOUT;
goto ERROR;
// timeout error recovery - start receiving new data
@ -289,13 +260,12 @@ ISR(IBMPC_INT_VECT)
// x x x x x x x x | *1 0 0 0 0 0 0 0 midway(8 bits received)
// b6 b5 b4 b3 b2 b1 b0 1 | 0 *1 0 0 0 0 0 0 XT_IBM-midway ^1
// b7 b6 b5 b4 b3 b2 b1 b0 | 0 *1 0 0 0 0 0 0 AT-midway ^1
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 *1 0 0 0 0 0 0 XT_Clone-done ^3
// b6 b5 b4 b3 b2 b1 b0 1 | 1 *1 0 0 0 0 0 0 XT_IBM-error ^3
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 *1 0 0 0 0 0 0 XT_Clone-done
// pr b7 b6 b5 b4 b3 b2 b1 | 0 0 *1 0 0 0 0 0 AT-midway[b0=0]
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 0 *1 0 0 0 0 0 XT_IBM-done ^2
// pr b7 b6 b5 b4 b3 b2 b1 | 1 0 *1 0 0 0 0 0 AT-midway[b0=1] ^2
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 1 *1 0 0 0 0 0 XT_IBM-error-done
// x x x x x x x x | x 1 1 0 0 0 0 0 illegal
// x x x x x x x x | 0 1 *1 0 0 0 0 0 illegal
// x x x x x x x x | 1 1 *1 0 0 0 0 0 illegal
// st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0 AT-done
// x x x x x x x x | x x 1 *1 0 0 0 0 illegal
// all other states than above illegal
@ -311,101 +281,120 @@ ISR(IBMPC_INT_VECT)
// midway
goto NEXT;
break;
case 0b11000000: // ^3
{
uint8_t us = 100;
// wait for rising and falling edge of b7 of XT_IBM
while (!(IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT)) && us) { wait_us(1); us--; }
while ( IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT) && us) { wait_us(1); us--; }
if (us) {
// XT_IBM-error: read start(0) as 1
goto NEXT;
} else {
// XT_Clone-done
ibmpc_isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_CLONE;
goto DONE;
}
}
break;
case 0b11100000:
// XT_IBM-error-done
ibmpc_isr_debug = isr_state;
case 0b11000000:
// XT_Clone-done
isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_ERROR;
protocol = IBMPC_PROTOCOL_XT_CLONE;
goto DONE;
break;
case 0b10100000: // ^2
{
uint8_t us = 100;
// wait for rising and falling edge of AT stop bit to discriminate between XT and AT
while (!(IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT)) && us) { wait_us(1); us--; }
while ( IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT) && us) { wait_us(1); us--; }
if (!protocol) {
while (!(IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
while ( (IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
} else if (protocol == IBMPC_PROTOCOL_XT_IBM) {
us = 0;
}
if (us) {
// found stop bit: AT-midway - process the stop bit in next ISR
goto NEXT;
} else {
// no stop bit: XT_IBM-done
ibmpc_isr_debug = isr_state;
isr_debug = isr_state;
isr_state = isr_state>>8;
ibmpc_protocol = IBMPC_PROTOCOL_XT_IBM;
protocol = IBMPC_PROTOCOL_XT_IBM;
goto DONE;
}
}
}
break;
case 0b00010000:
case 0b10010000:
case 0b01010000:
case 0b11010000:
// AT-done
// TODO: parity check?
ibmpc_isr_debug = isr_state;
isr_debug = isr_state;
// Detect AA with parity error for AT/XT Auto-Switching support
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-Keyboard-Converter#atxt-auto-switching
// isr_state: st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0
// 1 '0' 1 0 1 0 1 0 | 1 0 0 *1 0 0 0 0
if (isr_state == 0xAA90) {
error = IBMPC_ERR_PARITY_AA;
goto ERROR;
}
// parit bit check
{
// isr_state: st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0
uint8_t p = (isr_state & 0x4000) ? 1 : 0;
p ^= (isr_state >> 6);
while (p & 0xFE) {
p = (p >> 1) ^ (p & 0x01);
}
if (p == 0) {
error = IBMPC_ERR_PARITY;
goto ERROR;
}
}
// stop bit check
if (isr_state & 0x8000) {
ibmpc_protocol = IBMPC_PROTOCOL_AT;
protocol = IBMPC_PROTOCOL_AT;
} else {
// Zenith Z-150 AT(beige/white lable) asserts stop bit as low
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
ibmpc_protocol = IBMPC_PROTOCOL_AT_Z150;
protocol = IBMPC_PROTOCOL_AT_Z150;
}
isr_state = isr_state>>6;
goto DONE;
break;
case 0b01100000:
case 0b11100000:
case 0b00110000:
case 0b10110000:
case 0b01110000:
case 0b11110000:
default: // xxxx_oooo(any 1 in low nibble)
// Illegal
ibmpc_isr_debug = isr_state;
ibmpc_error = IBMPC_ERR_ILLEGAL;
protocol = 0;
isr_debug = isr_state;
error = IBMPC_ERR_ILLEGAL;
goto ERROR;
break;
}
ERROR:
// error: eeFF
recv_data = (ibmpc_error<<8) | 0x00FF;
goto CLEAR;
DONE:
if ((isr_state & 0x00FF) == 0x00FF) {
// receive error code 0xFF
ibmpc_error = IBMPC_ERR_FF;
goto ERROR;
}
if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
// buffer full
ibmpc_error = IBMPC_ERR_FULL;
goto ERROR;
#ifdef SIEMENS_PCD_SUPPORT
// inhibit - https://github.com/tmk/tmk_keyboard/issues/747
if (protocol & IBMPC_PROTOCOL_AT) {
clock_lo();
wait_us(150);
clock_hi();
}
#endif
// store data
recv_data = recv_data<<8;
recv_data |= isr_state & 0xFF;
CLEAR:
ringbuf_put(isr_state & 0xFF);
if (ringbuf_is_full()) {
// Disable ISR if buffer is full
int_off();
// inhibit: clock_lo() instead of inhibit() for ISR optimization
clock_lo();
}
if (ringbuf_is_empty()) {
// buffer overflow
error = IBMPC_ERR_FULL;
}
goto END;
ERROR:
// inhibit: Use clock_lo() instead of inhibit() for ISR optimization
clock_lo();
END:
// clear for next data
isr_state = 0x8000;
NEXT:
@ -413,9 +402,25 @@ NEXT:
}
/* send LED state to keyboard */
void ibmpc_host_set_led(uint8_t led)
void IBMPC::host_set_led(uint8_t led)
{
if (0xFA == ibmpc_host_send(0xED)) {
ibmpc_host_send(led);
if (0xFA == host_send(0xED)) {
host_send(led);
}
}
// NOTE: With this ISR data line should be read within 5us after clock falling edge.
// Confirmed that ATmega32u4 can read data line in 2.5us from interrupt after
// ISR prologue pushs r18, r19, r20, r21, r24, r25 r30 and r31 with GCC 5.4.0
ISR(IBMPC_INT_VECT)
{
IBMPC::interface0.isr();
}
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1) && defined(IBMPC_INT_VECT1)
ISR(IBMPC_INT_VECT1)
{
IBMPC::interface1.isr();
}
#endif

View file

@ -1,204 +0,0 @@
/*
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
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.
*/
#ifndef IBMPC_H
#define IBMPC_H
#include <stdbool.h>
#include "wait.h"
#include "print.h"
/*
* IBM PC keyboard protocol
*
* PS/2 Resources
* --------------
* [1] The PS/2 Mouse/Keyboard Protocol
* http://www.computer-engineering.org/ps2protocol/
* Concise and thorough primer of PS/2 protocol.
*
* [2] Keyboard and Auxiliary Device Controller
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
* Signal Timing and Format
*
* [3] Keyboards(101- and 102-key)
* http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
* Keyboard Layout, Scan Code Set, POR, and Commands.
*
* [4] PS/2 Reference Manuals
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
* Collection of IBM Personal System/2 documents.
*
* [5] TrackPoint Engineering Specifications for version 3E
* https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
*/
#define IBMPC_ACK 0xFA
#define IBMPC_RESEND 0xFE
#define IBMPC_SET_LED 0xED
#define IBMPC_PROTOCOL_NO 0
#define IBMPC_PROTOCOL_AT 0x10
#define IBMPC_PROTOCOL_AT_Z150 0x11
#define IBMPC_PROTOCOL_XT 0x20
#define IBMPC_PROTOCOL_XT_IBM 0x21
#define IBMPC_PROTOCOL_XT_CLONE 0x22
#define IBMPC_PROTOCOL_XT_ERROR 0x23
// Error numbers
#define IBMPC_ERR_NONE 0
#define IBMPC_ERR_RECV 0x00
#define IBMPC_ERR_SEND 0x10
#define IBMPC_ERR_TIMEOUT 0x20
#define IBMPC_ERR_FULL 0x40
#define IBMPC_ERR_ILLEGAL 0x80
#define IBMPC_ERR_FF 0xF0
#define IBMPC_LED_SCROLL_LOCK 0
#define IBMPC_LED_NUM_LOCK 1
#define IBMPC_LED_CAPS_LOCK 2
extern volatile uint16_t ibmpc_isr_debug;
extern volatile uint8_t ibmpc_protocol;
extern volatile uint8_t ibmpc_error;
void ibmpc_host_init(void);
void ibmpc_host_enable(void);
void ibmpc_host_disable(void);
int16_t ibmpc_host_send(uint8_t data);
int16_t ibmpc_host_recv_response(void);
int16_t ibmpc_host_recv(void);
void ibmpc_host_isr_clear(void);
void ibmpc_host_set_led(uint8_t usb_led);
/*--------------------------------------------------------------------
* static functions
*------------------------------------------------------------------*/
#if defined(__AVR__)
/*
* Clock
*/
static inline void clock_lo(void)
{
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
}
static inline void clock_hi(void)
{
/* input with pull up */
IBMPC_CLOCK_DDR &= ~(1<<IBMPC_CLOCK_BIT);
IBMPC_CLOCK_PORT |= (1<<IBMPC_CLOCK_BIT);
}
static inline bool clock_in(void)
{
IBMPC_CLOCK_DDR &= ~(1<<IBMPC_CLOCK_BIT);
IBMPC_CLOCK_PORT |= (1<<IBMPC_CLOCK_BIT);
wait_us(1);
return IBMPC_CLOCK_PIN&(1<<IBMPC_CLOCK_BIT);
}
/*
* Data
*/
static inline void data_lo(void)
{
IBMPC_DATA_PORT &= ~(1<<IBMPC_DATA_BIT);
IBMPC_DATA_DDR |= (1<<IBMPC_DATA_BIT);
}
static inline void data_hi(void)
{
/* input with pull up */
IBMPC_DATA_DDR &= ~(1<<IBMPC_DATA_BIT);
IBMPC_DATA_PORT |= (1<<IBMPC_DATA_BIT);
}
static inline bool data_in(void)
{
IBMPC_DATA_DDR &= ~(1<<IBMPC_DATA_BIT);
IBMPC_DATA_PORT |= (1<<IBMPC_DATA_BIT);
wait_us(1);
return IBMPC_DATA_PIN&(1<<IBMPC_DATA_BIT);
}
#endif
static inline uint16_t wait_clock_lo(uint16_t us)
{
while (clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_clock_hi(uint16_t us)
{
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_data_lo(uint16_t us)
{
while (data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
static inline uint16_t wait_data_hi(uint16_t us)
{
while (!data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
/* idle state that device can send */
static inline void idle(void)
{
clock_hi();
data_hi();
}
/* inhibit device to send(AT), soft reset(XT) */
static inline void inhibit(void)
{
clock_lo();
data_hi();
}
/* inhibit device to send(XT) */
static inline void inhibit_xt(void)
{
clock_hi();
data_lo();
}
#endif

275
tmk_core/protocol/ibmpc.hpp Normal file
View file

@ -0,0 +1,275 @@
/*
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
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.
*/
#ifndef IBMPC_HPP
#define IBMPC_HPP
#include <stdbool.h>
#include "wait.h"
/*
* IBM PC keyboard protocol
*
* PS/2 Resources
* --------------
* [1] The PS/2 Mouse/Keyboard Protocol
* http://www.computer-engineering.org/ps2protocol/
* Concise and thorough primer of PS/2 protocol.
*
* [2] Keyboard and Auxiliary Device Controller
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
* Signal Timing and Format
*
* [3] Keyboards(101- and 102-key)
* http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
* Keyboard Layout, Scan Code Set, POR, and Commands.
*
* [4] PS/2 Reference Manuals
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
* Collection of IBM Personal System/2 documents.
*
* [5] TrackPoint Engineering Specifications for version 3E
* https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
*/
#define IBMPC_ACK 0xFA
#define IBMPC_RESEND 0xFE
#define IBMPC_SET_LED 0xED
#define IBMPC_PROTOCOL_NO 0
#define IBMPC_PROTOCOL_AT 0x10
#define IBMPC_PROTOCOL_AT_Z150 0x11
#define IBMPC_PROTOCOL_XT 0x20
#define IBMPC_PROTOCOL_XT_IBM 0x21
#define IBMPC_PROTOCOL_XT_CLONE 0x22
// Error numbers
#define IBMPC_ERR_NONE 0
#define IBMPC_ERR_PARITY 0x01
#define IBMPC_ERR_PARITY_AA 0x02
#define IBMPC_ERR_SEND 0x10
#define IBMPC_ERR_TIMEOUT 0x20
#define IBMPC_ERR_FULL 0x40
#define IBMPC_ERR_ILLEGAL 0x80
#define IBMPC_LED_SCROLL_LOCK 0
#define IBMPC_LED_NUM_LOCK 1
#define IBMPC_LED_CAPS_LOCK 2
class IBMPC
{
public:
static IBMPC interface0;
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1)
static IBMPC interface1;
#endif
volatile uint16_t isr_debug;
volatile uint8_t protocol;
volatile uint8_t error;
void host_init(void);
void host_enable(void);
void host_disable(void);
int16_t host_send(uint8_t data);
int16_t host_recv_response(void);
int16_t host_recv(void);
void host_isr_clear(void);
void host_set_led(uint8_t led);
IBMPC(uint8_t clock, uint8_t data) :
isr_debug(IBMPC_ERR_NONE), protocol(IBMPC_PROTOCOL_NO), error(IBMPC_ERR_NONE),
isr_state(0x8000), timer_start(0), clock_bit(clock), data_bit(data),
clock_mask(1 << clock), data_mask(1 << data) {
};
void isr(void);
private:
volatile uint16_t isr_state;
uint8_t timer_start;
/* ring buffer */
// Size should be power of 2
#define RINGBUF_SIZE 16
uint8_t rb_head;
uint8_t rb_tail;
uint8_t rb_buffer[RINGBUF_SIZE];
const uint8_t clock_bit, data_bit;
const uint8_t clock_mask, data_mask;
inline void clock_lo(void) __attribute__((__always_inline__)) // needed for ISR optimization
{
IBMPC_CLOCK_PORT &= ~clock_mask;
IBMPC_CLOCK_DDR |= clock_mask;
}
inline void clock_hi(void)
{
/* input with pull up */
IBMPC_CLOCK_DDR &= ~clock_mask;
IBMPC_CLOCK_PORT |= clock_mask;
}
inline bool clock_in(void)
{
IBMPC_CLOCK_DDR &= ~clock_mask;
IBMPC_CLOCK_PORT |= clock_mask;
wait_us(1);
return IBMPC_CLOCK_PIN & clock_mask;
}
inline void data_lo(void)
{
IBMPC_DATA_PORT &= ~data_mask;
IBMPC_DATA_DDR |= data_mask;
}
inline void data_hi(void)
{
/* input with pull up */
IBMPC_DATA_DDR &= ~data_mask;
IBMPC_DATA_PORT |= data_mask;
}
inline bool data_in(void)
{
IBMPC_DATA_DDR &= ~data_mask;
IBMPC_DATA_PORT |= data_mask;
wait_us(1);
return IBMPC_DATA_PIN & data_mask;
}
inline uint16_t wait_clock_lo(uint16_t us)
{
while (clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
inline uint16_t wait_clock_hi(uint16_t us)
{
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
inline uint16_t wait_data_lo(uint16_t us)
{
while (data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
inline uint16_t wait_data_hi(uint16_t us)
{
while (!data_in() && us) { asm(""); wait_us(1); us--; }
return us;
}
/* idle state that device can send */
inline void idle(void)
{
clock_hi();
data_hi();
}
/* inhibit device to send(AT), soft reset(XT) */
inline void inhibit(void)
{
clock_lo();
data_hi();
}
/* inhibit device to send(XT) */
inline void inhibit_xt(void)
{
clock_hi();
data_lo();
}
void int_init(void)
{
// interrupt at falling edge
if (clock_bit < 4) {
EICRA |= (0x2 << ((clock_bit&0x3)*2));
} else {
EICRB |= (0x2 << ((clock_bit&0x3)*2));
}
}
void int_on(void)
{
EIFR |= clock_mask;
EIMSK |= clock_mask;
}
inline void int_off(void) __attribute__((__always_inline__)) // needed for ISR optimization
{
EIMSK &= ~clock_mask;
}
/*
* ring buffer
*/
inline int16_t ringbuf_get(void) __attribute__((__always_inline__))
{
if (ringbuf_is_empty()) return -1;
uint8_t data = rb_buffer[rb_tail];
rb_tail++;
rb_tail &= (RINGBUF_SIZE - 1);
return data;
}
inline void ringbuf_put(uint8_t data) __attribute__((__always_inline__))
{
rb_buffer[rb_head] = data;
rb_head++;
rb_head &= (RINGBUF_SIZE - 1);
}
inline bool ringbuf_is_empty(void) __attribute__((__always_inline__))
{
return (rb_head == rb_tail);
}
inline bool ringbuf_is_full(void) __attribute__((__always_inline__))
{
return (((rb_head + 1) & (RINGBUF_SIZE - 1)) == rb_tail);
}
inline void ringbuf_reset(void) __attribute__((__always_inline__))
{
rb_head = 0;
rb_tail = 0;
}
};
#endif

View file

@ -4,6 +4,10 @@ TMK_LUFA_DIR = protocol/lufa
TMK_LUFA_PATH ?= $(TMK_LUFA_DIR)/lufa-abcminiuser
# Version string
TMK_LUFA_VERSION := $(shell (cd $(TMK_DIR)/$(TMK_LUFA_PATH); git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
OPT_DEFS += -DTMK_LUFA_VERSION=$(TMK_LUFA_VERSION)
# Create the LUFA source path variables by including the LUFA makefile
ifneq (, $(wildcard $(TMK_DIR)/$(TMK_LUFA_PATH)/LUFA/Build/LUFA/lufa-sources.mk))
LUFA_PATH = $(TMK_LUFA_PATH)/LUFA
@ -47,7 +51,7 @@ TMK_LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_E
TMK_LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
TMK_LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361
ifeq ($(MCU),atmega32u2)
ifeq (atmega32u2,$(strip $(MCU)))
TMK_LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT
endif

View file

@ -44,8 +44,11 @@
/*******************************************************************************
* HID Report Descriptors
******************************************************************************/
#ifndef NO_KEYBOARD
const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{
#ifndef NKRO_ENABLE
/* 6KRO - Boot protocol */
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x06), /* Keyboard */
HID_RI_COLLECTION(8, 0x01), /* Application */
@ -81,29 +84,65 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
};
#else
/* NKRO - Report protocol */
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x06), /* Keyboard */
HID_RI_COLLECTION(8, 0x01), /* Application */
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
#ifdef MOUSE_ENABLE
HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
HID_RI_REPORT_COUNT(8, 0x05),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
#endif
};
#endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
{
#ifdef MOUSE_ENABLE
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x02), /* Mouse */
HID_RI_COLLECTION(8, 0x01), /* Application */
HID_RI_USAGE(8, 0x01), /* Pointer */
HID_RI_COLLECTION(8, 0x00), /* Physical */
HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
HID_RI_USAGE_PAGE(8, 0x09), /* Button */
HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */
HID_RI_USAGE_MAXIMUM(8, 0x08), /* Button 8 */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
HID_RI_REPORT_COUNT(8, 0x05),
HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_REPORT_COUNT(8, 0x01),
HID_RI_REPORT_SIZE(8, 0x03),
HID_RI_INPUT(8, HID_IOF_CONSTANT),
#ifndef MOUSE_EXT_REPORT
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x30), /* Usage X */
HID_RI_USAGE(8, 0x31), /* Usage Y */
@ -112,6 +151,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
#else
/* Boot protocol XY ignored in Report protocol */
HID_RI_USAGE_PAGE(8, 0xff), /* Vendor */
HID_RI_USAGE(8, 0xff), /* Vendor */
HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x30), /* Usage X */
HID_RI_USAGE(8, 0x31), /* Usage Y */
HID_RI_LOGICAL_MINIMUM(16, -32767),
HID_RI_LOGICAL_MAXIMUM(16, 32767),
HID_RI_REPORT_COUNT(8, 0x02),
HID_RI_REPORT_SIZE(8, 16),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
#endif
HID_RI_USAGE(8, 0x38), /* Wheel */
HID_RI_LOGICAL_MINIMUM(8, -127),
@ -130,12 +188,9 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_END_COLLECTION(0),
HID_RI_END_COLLECTION(0),
};
#endif
#ifdef EXTRAKEY_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
{
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x80), /* System Control */
HID_RI_COLLECTION(8, 0x01), /* Application */
@ -161,6 +216,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
HID_RI_REPORT_COUNT(8, 1),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
#endif
};
#endif
@ -186,7 +242,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
};
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
{
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
@ -272,6 +328,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
/*
* Keyboard
*/
#ifndef NO_KEYBOARD
.Keyboard_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@ -305,14 +362,20 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
#ifdef NKRO_ENABLE
.EndpointSize = NKRO_EPSIZE,
.PollingIntervalMS = 0x01
#else
.EndpointSize = KEYBOARD_EPSIZE,
.PollingIntervalMS = 0x0A
#endif
},
#endif
/*
* Mouse
*/
#ifdef MOUSE_ENABLE
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
.Mouse_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@ -323,8 +386,13 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
#if defined(MOUSE_ENABLE)
.SubClass = HID_CSCP_BootSubclass,
.Protocol = HID_CSCP_MouseBootProtocol,
#else
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
#endif
.InterfaceStrIndex = NO_DESCRIPTOR
},
@ -347,49 +415,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MOUSE_EPSIZE,
.PollingIntervalMS = 0x0A
},
#endif
/*
* Extra
*/
#ifdef EXTRAKEY_ENABLE
.Extrakey_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = EXTRAKEY_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Extrakey_HID =
{
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
.HIDSpec = VERSION_BCD(1,1,1),
.CountryCode = 0x00,
.TotalReportDescriptors = 1,
.HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(ExtrakeyReport)
},
.Extrakey_INEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = EXTRAKEY_EPSIZE,
.PollingIntervalMS = 0x0A
.PollingIntervalMS = 0x01
},
#endif
@ -404,7 +430,8 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.InterfaceNumber = CONSOLE_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 2,
//.TotalEndpoints = 2,
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_NonBootSubclass,
@ -434,6 +461,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.PollingIntervalMS = 0x01
},
/*
.Console_OUTEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
@ -443,12 +471,13 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointSize = CONSOLE_EPSIZE,
.PollingIntervalMS = 0x01
},
*/
#endif
/*
* NKRO
*/
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
.NKRO_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@ -561,29 +590,25 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
break;
case HID_DTYPE_HID:
switch (wIndex) {
#ifndef NO_KEYBOARD
case KEYBOARD_INTERFACE:
Address = &ConfigurationDescriptor.Keyboard_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#ifdef MOUSE_ENABLE
#endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
case MOUSE_INTERFACE:
Address = &ConfigurationDescriptor.Mouse_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
#ifdef EXTRAKEY_ENABLE
case EXTRAKEY_INTERFACE:
Address = &ConfigurationDescriptor.Extrakey_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
#ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE:
Address = &ConfigurationDescriptor.Console_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
case NKRO_INTERFACE:
Address = &ConfigurationDescriptor.NKRO_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
@ -593,29 +618,25 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
break;
case HID_DTYPE_Report:
switch (wIndex) {
#ifndef NO_KEYBOARD
case KEYBOARD_INTERFACE:
Address = &KeyboardReport;
Size = sizeof(KeyboardReport);
break;
#ifdef MOUSE_ENABLE
#endif
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
case MOUSE_INTERFACE:
Address = &MouseReport;
Size = sizeof(MouseReport);
break;
#endif
#ifdef EXTRAKEY_ENABLE
case EXTRAKEY_INTERFACE:
Address = &ExtrakeyReport;
Size = sizeof(ExtrakeyReport);
break;
#endif
#ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE:
Address = &ConsoleReport;
Size = sizeof(ConsoleReport);
break;
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
case NKRO_INTERFACE:
Address = &NKROReport;
Size = sizeof(NKROReport);

View file

@ -52,34 +52,29 @@ typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
#ifndef NO_KEYBOARD
// Keyboard HID Interface
USB_Descriptor_Interface_t Keyboard_Interface;
USB_HID_Descriptor_HID_t Keyboard_HID;
USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
#endif
#ifdef MOUSE_ENABLE
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
// Mouse HID Interface
USB_Descriptor_Interface_t Mouse_Interface;
USB_HID_Descriptor_HID_t Mouse_HID;
USB_Descriptor_Endpoint_t Mouse_INEndpoint;
#endif
#ifdef EXTRAKEY_ENABLE
// Extrakey HID Interface
USB_Descriptor_Interface_t Extrakey_Interface;
USB_HID_Descriptor_HID_t Extrakey_HID;
USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
#endif
#ifdef CONSOLE_ENABLE
// Console HID Interface
USB_Descriptor_Interface_t Console_Interface;
USB_HID_Descriptor_HID_t Console_HID;
USB_Descriptor_Endpoint_t Console_INEndpoint;
USB_Descriptor_Endpoint_t Console_OUTEndpoint;
// USB_Descriptor_Endpoint_t Console_OUTEndpoint;
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
// NKRO HID Interface
USB_Descriptor_Interface_t NKRO_Interface;
USB_HID_Descriptor_HID_t NKRO_HID;
@ -89,27 +84,25 @@ typedef struct
/* index of interface */
#define KEYBOARD_INTERFACE 0
#ifndef NO_KEYBOARD
# define KEYBOARD_INTERFACE 0
#else
# define KEYBOARD_INTERFACE -1
#endif
#ifdef MOUSE_ENABLE
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
# define MOUSE_INTERFACE (KEYBOARD_INTERFACE + 1)
#else
# define MOUSE_INTERFACE KEYBOARD_INTERFACE
#endif
#ifdef EXTRAKEY_ENABLE
# define EXTRAKEY_INTERFACE (MOUSE_INTERFACE + 1)
#else
# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
#endif
#ifdef CONSOLE_ENABLE
# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
# define CONSOLE_INTERFACE (MOUSE_INTERFACE + 1)
#else
# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
# define CONSOLE_INTERFACE MOUSE_INTERFACE
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
#else
# define NKRO_INTERFACE CONSOLE_INTERFACE
@ -121,28 +114,32 @@ typedef struct
// Endopoint number and size
#define KEYBOARD_IN_EPNUM 1
#ifndef NO_KEYBOARD
# define KEYBOARD_IN_EPNUM 1
#else
# define KEYBOARD_IN_EPNUM 0
#endif
#ifdef MOUSE_ENABLE
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
# define MOUSE_IN_EPNUM (KEYBOARD_IN_EPNUM + 1)
#else
# define MOUSE_IN_EPNUM KEYBOARD_IN_EPNUM
#endif
#ifdef EXTRAKEY_ENABLE
# define EXTRAKEY_IN_EPNUM (MOUSE_IN_EPNUM + 1)
#else
# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM
#endif
#ifdef CONSOLE_ENABLE
# define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
# define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 1)
// ATMega32U2 doesn't support double bank on endpoint 1 and 2, use 3 or 4
# if MOUSE_IN_EPNUM < 2
# define CONSOLE_IN_EPNUM 3
# define CONSOLE_OUT_EPNUM 3
# else
# define CONSOLE_IN_EPNUM (MOUSE_IN_EPNUM + 1)
# define CONSOLE_OUT_EPNUM (MOUSE_IN_EPNUM + 1)
# endif
#else
# define CONSOLE_OUT_EPNUM EXTRAKEY_IN_EPNUM
# define CONSOLE_OUT_EPNUM MOUSE_IN_EPNUM
#endif
#ifdef NKRO_ENABLE
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
#else
# define NKRO_IN_EPNUM CONSOLE_OUT_EPNUM
@ -150,13 +147,18 @@ typedef struct
/* Check number of endpoints. ATmega32u2 has only four except for control endpoint. */
#if defined(__AVR_ATmega32U2__) && NKRO_IN_EPNUM > 4
# error "Endpoints are not available enough to support all functions. Disable some of build options in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO)"
# error "Endpoints are not available enough to support all functions. Disable some of build options in Makefile.(MOUSEKEY, CONSOLE, NKRO)"
#endif
#define KEYBOARD_EPSIZE 8
#if defined(MOUSE_EXT_REPORT)
#define MOUSE_EPSIZE 10
#else
#define MOUSE_EPSIZE 8
#define EXTRAKEY_EPSIZE 8
#endif
#define CONSOLE_EPSIZE 32
#define NKRO_EPSIZE 32

View file

@ -41,6 +41,7 @@
#include "host_driver.h"
#include "keyboard.h"
#include "action.h"
#include "action_util.h"
#include "led.h"
#include "sendchar.h"
#include "ringbuf.h"
@ -68,26 +69,35 @@
//#define TMK_LUFA_DEBUG
#ifndef NO_KEYBOARD
uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1;
static uint8_t keyboard_led_stats = 0;
static report_keyboard_t keyboard_report_sent = (report_keyboard_t){};
#endif
static report_keyboard_t keyboard_report_sent;
#ifdef MOUSE_ENABLE
uint8_t mouse_protocol = 1;
#endif
/* Host driver */
#ifndef NO_KEYBOARD
static uint8_t keyboard_leds(void);
static void send_keyboard(report_keyboard_t *report);
#endif
static void send_mouse(report_mouse_t *report);
static void send_system(uint16_t data);
static void send_consumer(uint16_t data);
host_driver_t lufa_driver = {
keyboard_leds,
send_keyboard,
send_mouse,
send_system,
send_consumer
#ifndef NO_KEYBOARD
.keyboard_leds = keyboard_leds,
.send_keyboard = send_keyboard,
#endif
.send_mouse = send_mouse,
.send_system = send_system,
.send_consumer = send_consumer
};
@ -95,7 +105,11 @@ host_driver_t lufa_driver = {
* Console
******************************************************************************/
#ifdef CONSOLE_ENABLE
#define SENDBUF_SIZE 256
# ifdef _AVR_ATmega32U2_H_
# define SENDBUF_SIZE 128
# else
# define SENDBUF_SIZE 256
# endif
static uint8_t sbuf[SENDBUF_SIZE];
static ringbuf_t sendbuf = {
.buffer = sbuf,
@ -296,6 +310,19 @@ void EVENT_USB_Device_Reset(void)
#ifdef TMK_LUFA_DEBUG
print("[R]");
#endif
// reset to initial state: protocol to Report(default)
#ifndef NO_KEYBOARD
keyboard_protocol = 1;
keyboard_idle = 0;
keyboard_led_stats = 0;
keyboard_report_sent = (report_keyboard_t){};
// keyboard_report keys/bits part is not compatible between Boot and Report protocol
clear_keys();
#endif
#ifdef MOUSE_ENABLE
mouse_protocol = 1;
#endif
}
void EVENT_USB_Device_Suspend()
@ -327,33 +354,35 @@ void EVENT_USB_Device_ConfigurationChanged(void)
#endif
bool ConfigSuccess = true;
#ifndef NO_KEYBOARD
/* Setup Keyboard HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
#ifdef NKRO_ENABLE
NKRO_EPSIZE,
#else
KEYBOARD_EPSIZE,
#endif
ENDPOINT_BANK_SINGLE);
#endif
#ifdef MOUSE_ENABLE
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
/* Setup Mouse HID Report Endpoint */
ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef EXTRAKEY_ENABLE
/* Setup Extra HID Report Endpoint */
ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef CONSOLE_ENABLE
// ATMega32U2 doesn't support double bank on endpoint 1 and 2, use 3 or 4
/* Setup Console HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE);
#if 0
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#endif
#ifdef NKRO_ENABLE
#ifdef NKRO_6KRO_ENABLE
/* Setup NKRO HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
@ -378,15 +407,16 @@ Other Device Required Optional Optional Optional Optional Opti
*/
void EVENT_USB_Device_ControlRequest(void)
{
uint8_t* ReportData = NULL;
uint8_t ReportSize = 0;
/* Handle HID Class specific requests */
switch (USB_ControlRequest.bRequest)
{
case HID_REQ_GetReport:
#ifndef NO_KEYBOARD
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
uint8_t* ReportData = NULL;
uint8_t ReportSize = 0;
Endpoint_ClearSETUP();
// Interface
@ -405,6 +435,7 @@ void EVENT_USB_Device_ControlRequest(void)
xprintf("[r%d]", USB_ControlRequest.wIndex);
#endif
}
#endif
break;
case HID_REQ_SetReport:
@ -413,8 +444,9 @@ void EVENT_USB_Device_ControlRequest(void)
// Interface
switch (USB_ControlRequest.wIndex) {
#ifndef NO_KEYBOARD
case KEYBOARD_INTERFACE:
#ifdef NKRO_ENABLE
#ifdef NKRO_6KRO_ENABLE
case NKRO_INTERFACE:
#endif
Endpoint_ClearSETUP();
@ -428,9 +460,10 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
#ifdef TMK_LUFA_DEBUG
xprintf("[L%d]", USB_ControlRequest.wIndex);
xprintf("[L%d %02X]", USB_ControlRequest.wIndex, keyboard_led_stats);
#endif
break;
#endif
}
}
@ -440,6 +473,7 @@ void EVENT_USB_Device_ControlRequest(void)
case HID_REQ_GetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
#ifndef NO_KEYBOARD
if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady()));
@ -450,34 +484,58 @@ void EVENT_USB_Device_ControlRequest(void)
print("[p]");
#endif
}
#endif
#if defined(MOUSE_ENABLE)
if (USB_ControlRequest.wIndex == MOUSE_INTERFACE) {
Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady()));
Endpoint_Write_8(mouse_protocol);
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
#endif
}
break;
case HID_REQ_SetProtocol:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
#ifndef NO_KEYBOARD
if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
clear_keyboard();
#ifdef TMK_LUFA_DEBUG
print("[P]");
xprintf("[P%d %04X]", USB_ControlRequest.wIndex, USB_ControlRequest.wValue);
#endif
}
#endif
#if defined(MOUSE_ENABLE)
if (USB_ControlRequest.wIndex == MOUSE_INTERFACE) {
Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
mouse_protocol = (USB_ControlRequest.wValue & 0xFF);
#ifdef TMK_LUFA_DEBUG
xprintf("[P%d %04X]", USB_ControlRequest.wIndex, USB_ControlRequest.wValue);
#endif
}
#endif
}
break;
case HID_REQ_SetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
#ifndef NO_KEYBOARD
Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
#ifdef TMK_LUFA_DEBUG
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
xprintf("[I%d %04X]", USB_ControlRequest.wIndex, USB_ControlRequest.wValue);
#endif
#endif
}
@ -485,6 +543,7 @@ void EVENT_USB_Device_ControlRequest(void)
case HID_REQ_GetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
#ifndef NO_KEYBOARD
Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady()));
Endpoint_Write_8(keyboard_idle);
@ -492,6 +551,7 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_ClearStatusStage();
#ifdef TMK_LUFA_DEBUG
print("[i]");
#endif
#endif
}
@ -502,6 +562,7 @@ void EVENT_USB_Device_ControlRequest(void)
/*******************************************************************************
* Host driver
******************************************************************************/
#ifndef NO_KEYBOARD
static uint8_t keyboard_leds(void)
{
return keyboard_led_stats;
@ -515,10 +576,14 @@ static void send_keyboard(report_keyboard_t *report)
return;
/* Select the Keyboard Report Endpoint */
#ifdef NKRO_ENABLE
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
if (keyboard_protocol && keyboard_nkro) {
/* Report protocol - NKRO */
#if defined(NKRO_6KRO_ENABLE)
Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
#else
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
#endif
/* Check if write ready for a polling interval around 1ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(8);
@ -546,6 +611,7 @@ static void send_keyboard(report_keyboard_t *report)
keyboard_report_sent = *report;
}
#endif
static void send_mouse(report_mouse_t *report)
{
@ -563,7 +629,14 @@ static void send_mouse(report_mouse_t *report)
if (!Endpoint_IsReadWriteAllowed()) return;
/* Write Mouse Report Data */
Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
if (mouse_protocol) {
// Report
Endpoint_Write_8(REPORT_ID_MOUSE);
Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
} else {
// Boot
Endpoint_Write_Stream_LE(report, 3, NULL);
}
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
@ -578,11 +651,19 @@ static void send_system(uint16_t data)
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
report_extra_t r = {
.report_id = REPORT_ID_SYSTEM,
.usage = data - SYSTEM_POWER_DOWN + 1
};
Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
#ifdef MOUSE_ENABLE
// Not send while mouse is set to Boot Protocol
if (mouse_protocol == 0)
return;
#endif
report_extra_t r = { .report_id = REPORT_ID_SYSTEM };
if (data < SYSTEM_POWER_DOWN) {
r.usage = 0;
} else {
r.usage = data - SYSTEM_POWER_DOWN + 1;
}
Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@ -601,11 +682,17 @@ static void send_consumer(uint16_t data)
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
#ifdef MOUSE_ENABLE
// Not send while mouse is set to Boot Protocol
if (mouse_protocol == 0)
return;
#endif
report_extra_t r = {
.report_id = REPORT_ID_CONSUMER,
.usage = data
};
Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@ -677,21 +764,40 @@ int main(void)
print_set_sendchar(sendchar);
host_set_driver(&lufa_driver);
print("\n\nTMK:" STR(TMK_VERSION) "/LUFA\n\n");
print("\nTMK:" STR(TMK_VERSION) "/LUFA:" STR(TMK_LUFA_VERSION)
#ifdef TMK_USB_HOST_SHIELD_VERSION
"/UHS2:" STR(TMK_USB_HOST_SHIELD_VERSION)
#endif
"\n");
hook_early_init();
#ifndef NO_KEYBOARD
keyboard_setup();
#endif
setup_usb();
#ifdef SLEEP_LED_ENABLE
sleep_led_init();
#endif
sei();
#ifndef NO_KEYBOARD
keyboard_init();
#else
// TODO: keyboard_init() should be used only for things related to keyboard
timer_init();
#endif
#ifndef NO_USB_STARTUP_WAIT_LOOP
/* wait for USB startup */
while (USB_DeviceState != DEVICE_STATE_Configured) {
while (USB_DeviceState != DEVICE_STATE_Configured
#ifdef CONSOLE_ENABLE
|| !console_is_ready()
#endif
) {
#if defined(INTERRUPT_CONTROL_ENDPOINT)
;
#else
@ -704,7 +810,7 @@ int main(void)
hook_late_init();
print("\nKeyboard start.\n");
print("\nLoop start.\n");
while (1) {
#ifndef NO_USB_SUSPEND_LOOP
while (USB_DeviceState == DEVICE_STATE_Suspended) {
@ -712,7 +818,11 @@ int main(void)
}
#endif
hook_main_loop();
#ifndef NO_KEYBOARD
keyboard_task();
#endif
#ifdef CONSOLE_ENABLE
console_task();
@ -732,10 +842,13 @@ void hook_early_init(void) {}
__attribute__((weak))
void hook_late_init(void) {}
#ifndef NO_KEYBOARD
static uint8_t _led_stats = 0;
#endif
__attribute__((weak))
void hook_usb_suspend_entry(void)
{
#ifndef NO_KEYBOARD
// Turn off LED to save power and keep its status to resotre it later.
// LED status will be updated by keyboard_task() in main loop hopefully.
_led_stats = keyboard_led_stats;
@ -745,6 +858,7 @@ void hook_usb_suspend_entry(void)
matrix_clear();
clear_keyboard();
#endif
#ifdef SLEEP_LED_ENABLE
sleep_led_enable();
#endif
@ -770,8 +884,10 @@ void hook_usb_wakeup(void)
sleep_led_disable();
#endif
#ifndef NO_KEYBOARD
// Restore LED status and update at keyboard_task() in main loop
keyboard_led_stats = _led_stats;
#endif
// Calling long task here can prevent USB state transition
}

View file

@ -494,10 +494,19 @@ RAW CODE:
* 0x71, 0x79,DD / 0xF1, 0x79, 0xUU
MODEL NUMBER:
M0110: 0x09 00001001 : model number 4 (100)
M0110A: 0x0B 00001011 : model number 5 (101)
M0110 & M0120: ???
MODEL CODE:
Model Code Layout Made in Desc
---------------------------------------------------------------------
M0110(GS536) 0x03 US USA
M0110(GS624) 0x09 US USA
M0110F 0x03 French Ireland https://github.com/tmk/tmk_keyboard/issues/771
M0110A(M923) 0x0B US
M0110AJ(M839) 0x0B US
M0110AJ(A615) 0x0B US
M0120(BCG9GRM0120) 0x11
M0120 & M0110(G536) 0x13
M0120 & M0110(G624) 0x19
M0120 & M0110A(M923) 0x1B
Scan Code
@ -572,8 +581,8 @@ Scan Code
References
----------
Technical Info for 128K/512K 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
https://www.apple.asimov.net/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
https://www.apple.asimov.net/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
Protocol:
Page 20 of Tech Info for 128K/512K
http://www.mac.linux-m68k.org/devel/plushw.php

View file

@ -1,168 +0,0 @@
/*
Copyright 2012 Jun WAKO <wakojun@gmail.com>
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.
*/
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "news.h"
void news_init(void)
{
NEWS_KBD_RX_INIT();
}
// RX ring buffer
#define RBUF_SIZE 8
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;
uint8_t news_recv(void)
{
uint8_t data = 0;
if (rbuf_head == rbuf_tail) {
return 0;
}
data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
return data;
}
// USART RX complete interrupt
ISR(NEWS_KBD_RX_VECT)
{
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
if (next != rbuf_tail) {
rbuf[rbuf_head] = NEWS_KBD_RX_DATA;
rbuf_head = next;
}
}
/*
SONY NEWS Keyboard Protocol
===========================
Resources
---------
Mouse protocol of NWA-5461(Japanese)
http://groups.google.com/group/fj.sys.news/browse_thread/thread/a01b3e3ac6ae5b2d
SONY NEWS Info(Japanese)
http://katsu.watanabe.name/doc/sonynews/
Pinouts
-------
EIA 232 male connector from NWP-5461
-------------
\ 1 2 3 4 5 /
\ 6 7 8 9 /
---------
1 VCC
2 BZ(Speaker)
3 Keyboard Data(from keyboard MCU TxD)
4 NC
5 GND
6 Unknown Input(to keyboard MCU RxD via schmitt trigger)
7 Mouse Data(from Mouse Ext connector)
8 Unknown Input(to Keyboard MCU Input via diode and buffer)
9 FG
NOTE: Two LED on keyboard are controlled by pin 6,8?
EIA 232 male connector from NWP-411A
-------------
\ 1 2 3 4 5 /
\ 6 7 8 9 /
---------
1 VCC
2 BZ(Speaker)
3 Keyboard Data(from keyboard MCU TxD)
4 NC
5 GND
6 NC
7 Mouse Data(from Mouse Ext connector)
8 NC
9 FG
NOTE: These are just from my guess and not confirmed.
Signaling
---------
~~~~~~~~~~ ____XOO0X111X222X333X444X555X666X777~~~~ ~~~~~~~
Idle Start LSB MSB Stop Idle
Idle: High
Start bit: Low
Stop bit: High
Bit order: LSB first
Baud rate: 9600
Interface: TTL level(5V) UART
NOTE: This is observed on NWP-5461 with its DIP switch all OFF.
Format
------
MSB LSB
7 6 5 4 3 2 1 0 bit
| | | | | | | |
| +-+-+-+-+-+-+-- scan code(00-7F)
+---------------- break flag: sets when released
Scan Codes
----------
SONY NEWS NWP-5461
,---. ,------------------------, ,------------------------. ,---------.
| 7A| | 01 | 02 | 03 | 04 | 05 | | 06 | 07 | 08 | 09 | 0A | | 68 | 69 | ,-----------.
`---' `------------------------' `------------------------' `---------' | 64| 65| 52|
,-------------------------------------------------------------. ,---. ,---------------|
| 0B| 0C| 0D| 0E| 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19 | | 6A| | 4B| 4C| 4D| 4E|
|-------------------------------------------------------------| |---| |---------------|
| 1A | 1B| 1C| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| | | 6B| | 4F| 50| 51| 56|
|---------------------------------------------------------' | |---| |---------------|
| 28 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35 | | 6C| | 53| 54| 55| |
|-------------------------------------------------------------| |---| |-----------| 5A|
| 36 | 37| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F| 40| 41| 42 | | 6D| | 57| 59| 58| |
|-------------------------------------------------------------| |---| |---------------|
| 43 | 44 | 45 | 46 | 47 | 48| 49| 4A | | 6E| | 66| 5B| 5C| 5D|
`-------------------------------------------------------------' `---' `---------------'
*/

View file

@ -1,51 +0,0 @@
/*
Copyright 2012 Jun WAKO <wakojun@gmail.com>
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.
*/
#ifndef NEWS_H
#define NEWS_H
/*
* Primitive PS/2 Library for AVR
*/
/* host role */
void news_init(void);
uint8_t news_recv(void);
/* device role */
#endif

View file

@ -59,16 +59,10 @@ static inline void query(void);
static inline void reset(void);
static inline uint32_t response(void);
/* The keyboard sends signal with 50us pulse width on OUT line
* while it seems to miss the 50us pulse on In line.
* next_kbd_set_leds() often fails to sync LED status with 50us
* but it works well with 51us(+1us) on TMK converter(ATMeaga32u2) at least.
* TODO: test on Teensy and Pro Micro configuration
*/
#define out_hi_delay(intervals) do { out_hi(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define out_lo_delay(intervals) do { out_lo(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define query_delay(intervals) do { query(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define reset_delay(intervals) do { reset(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define out_hi_delay(intervals) do { out_hi(); _delay_us((NEXT_KBD_TIMING) * intervals); } while (0);
#define out_lo_delay(intervals) do { out_lo(); _delay_us((NEXT_KBD_TIMING) * intervals); } while (0);
#define query_delay(intervals) do { query(); _delay_us((NEXT_KBD_TIMING) * intervals); } while (0);
#define reset_delay(intervals) do { reset(); _delay_us((NEXT_KBD_TIMING) * intervals); } while (0);
void next_kbd_init(void)
{
@ -144,34 +138,14 @@ static inline uint32_t response(void)
sei();
return 0;
}
_delay_us(NEXT_KBD_TIMING / 2);
_delay_us(NEXT_KBD_TIMING / 2 - 1);
for (; i < 22; i++)
{
if (NEXT_KBD_READ)
{
data |= ((uint32_t) 1 << i);
/* Note:
* My testing with the ATmega32u4 showed that there might
* something wrong with the timing here; by the end of the
* second data byte some of the modifiers can get bumped out
* to the next bit over if we just cycle through the data
* based on the expected interval. There is a bit (i = 10)
* in the middle of the data that is always on followed by
* one that is always off - so we'll use that to reset our
* timing in case we've gotten ahead of the keyboard;
*/
if (i == 10)
{
i++;
while (NEXT_KBD_READ) ;
_delay_us(NEXT_KBD_TIMING / 2);
}
} else {
/* redundant - but I don't want to remove if it might screw
* up the timing
*/
data |= ((uint32_t) 0 << i);
data |= (uint32_t)1 << 22;
}
data >>= 1;
_delay_us(NEXT_KBD_TIMING);
}

View file

@ -51,7 +51,9 @@ POSSIBILITY OF SUCH DAMAGE.
#define NEXT_KBD_H
#define NEXT_KBD_KMBUS_IDLE 0x300600
#define NEXT_KBD_TIMING 50
// https://github.com/tmk/tmk_keyboard/issues/704
#define NEXT_KBD_TIMING 52
extern uint8_t next_kbd_error;

View file

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
static report_mouse_t mouse_report = {};
static uint8_t last_buttons;
static void print_usb_data(void);
@ -161,6 +162,7 @@ void ps2_mouse_task(void)
host_mouse_send(&mouse_report);
last_buttons = mouse_report.buttons;
print_usb_data();
}
// clear report
@ -171,6 +173,11 @@ void ps2_mouse_task(void)
mouse_report.buttons = 0;
}
uint8_t ps2_mouse_buttons(void)
{
return last_buttons;
}
static void print_usb_data(void)
{
if (!debug_mouse) return;

View file

@ -62,5 +62,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
uint8_t ps2_mouse_init(void);
void ps2_mouse_task(void);
uint8_t ps2_mouse_buttons(void);
#endif

View file

@ -29,5 +29,6 @@ static inline uint8_t serial_mouse_init(void)
}
void serial_mouse_task(void);
uint8_t serial_mouse_buttons(void);
#endif

View file

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
static uint8_t last_buttons;
static void print_usb_data(const report_mouse_t *report);
void serial_mouse_task(void)
@ -71,6 +72,7 @@ void serial_mouse_task(void)
print_usb_data(&report);
host_mouse_send(&report);
last_buttons = report.buttons;
return;
}
@ -111,6 +113,12 @@ void serial_mouse_task(void)
print_usb_data(&report);
host_mouse_send(&report);
last_buttons = report.buttons;
}
uint8_t serial_mouse_buttons(void)
{
return last_buttons;
}
static void print_usb_data(const report_mouse_t *report)

View file

@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define SERIAL_MOUSE_CENTER_SCROLL
static uint8_t last_buttons;
static void print_usb_data(const report_mouse_t *report);
void serial_mouse_task(void)
@ -78,6 +79,7 @@ void serial_mouse_task(void)
print_usb_data(&report);
host_mouse_send(&report);
last_buttons = report.buttons;
if (buffer[3] || buffer[4]) {
report.h = MAX((int8_t)buffer[3], -127);
@ -85,6 +87,7 @@ void serial_mouse_task(void)
print_usb_data(&report);
host_mouse_send(&report);
last_buttons = report.buttons;
}
return;
@ -117,9 +120,15 @@ void serial_mouse_task(void)
print_usb_data(&report);
host_mouse_send(&report);
last_buttons = report.buttons;
}
}
uint8_t serial_mouse_buttons(void)
{
return last_buttons;
}
static void print_usb_data(const report_mouse_t *report)
{
if (!debug_mouse)

View file

@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
* TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed.
*/
#define WAIT_US (1000000L/SERIAL_SOFT_BAUD)
#define WAIT_US (1000000L/SERIAL_SOFT_BAUD - 1)
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
#define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ())
@ -68,11 +68,10 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
/* debug for signal timing, see debug pin with oscilloscope */
#ifdef SERIAL_SOFT_DEBUG
#define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7)
#define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7)
#else
#ifndef SERIAL_SOFT_DEBUG_INIT
#define SERIAL_SOFT_DEBUG_INIT()
#endif
#ifndef SERIAL_SOFT_DEBUG_TGL
#define SERIAL_SOFT_DEBUG_TGL()
#endif
@ -86,7 +85,9 @@ void serial_init(void)
}
/* RX ring buffer */
#define RBUF_SIZE 8
#ifndef RBUF_SIZE
#define RBUF_SIZE 256
#endif
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;
@ -175,6 +176,9 @@ void serial_send(uint8_t data)
ISR(SERIAL_SOFT_RXD_VECT)
{
SERIAL_SOFT_DEBUG_TGL();
/* can be triggered by other pin. don't know why */
if (SERIAL_SOFT_RXD_IN()) { return; }
SERIAL_SOFT_RXD_INT_ENTER();
uint8_t data = 0;
@ -194,6 +198,7 @@ ISR(SERIAL_SOFT_RXD_VECT)
/* to center of start bit */
_delay_us(WAIT_US/2);
SERIAL_SOFT_DEBUG_TGL();
//if (SERIAL_SOFT_RXD_IN()) { return; }
do {
/* to center of next bit */
_delay_us(WAIT_US);

View file

@ -63,7 +63,9 @@ void serial_init(void)
}
// RX ring buffer
#ifndef RBUF_SIZE
#define RBUF_SIZE 256
#endif
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;

View file

@ -12,6 +12,10 @@ USB_HOST_SHIELD_SRC = \
$(USB_HOST_SHIELD_DIR)/parsetools.cpp \
$(USB_HOST_SHIELD_DIR)/message.cpp
# Version string
TMK_USB_HOST_SHIELD_VERSION := $(shell (cd $(TMK_DIR)/$(USB_HOST_SHIELD_DIR); git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
OPT_DEFS += -DTMK_USB_HOST_SHIELD_VERSION=$(TMK_USB_HOST_SHIELD_VERSION)
#

View file

@ -51,8 +51,10 @@ size_t Serial_::write(uint8_t c)
size_t Serial_::write(const uint8_t *buffer, size_t size)
{
sendchar(*buffer);
return 1;
for (int i = 0; i < size; i++) {
sendchar(buffer[i]);
}
return size;
}
Serial_::operator bool() {

View file

@ -12,6 +12,15 @@ void KBDReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *b
}
xprintf("\r\n");
/* Keyboard can send report in size other than 8 bytes
* https://github.com/tmk/tmk_keyboard/issues/773
// boot keyboard report length should be 8
if (len != 8) {
xprintf(" ignored\r\n");
return;
}
*/
// Rollover error
// Cherry: 0101010101010101
// https://geekhack.org/index.php?topic=69169.msg2638223#msg2638223

View file

@ -139,6 +139,7 @@ CFLAGS += -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
CFLAGS += -flto
ifdef CONFIG_H
CFLAGS += -include $(CONFIG_H)
endif
@ -173,6 +174,7 @@ CPPFLAGS += -Wundef
CPPFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
CPPFLAGS += -flto
ifdef CONFIG_H
CPPFLAGS += -include $(CONFIG_H)
endif
@ -189,6 +191,7 @@ endif
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
ASFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
ASFLAGS += -flto
ifdef CONFIG_H
ASFLAGS += -include $(CONFIG_H)
endif
@ -261,6 +264,7 @@ LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
# You can give EXTRALDFLAGS at 'make' command line.
LDFLAGS += $(EXTRALDFLAGS)
LDFLAGS += -flto
@ -334,10 +338,10 @@ MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC))))
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.cpp.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC))))
# Define all listing files.
LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.lst,$(patsubst %.S,$(OBJDIR)/%.lst,$(SRC))))
LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.cpp.lst,$(patsubst %.S,$(OBJDIR)/%.lst,$(SRC))))
# Compiler flags to generate dependency files.
@ -348,9 +352,9 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(subst /,_,$@).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
ALL_CFLAGS = -mmcu=$(MCU) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
ALL_CFLAGS = -mmcu=$(MCU) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) $(EXTRACFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) $(EXTRACPPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) $(EXTRAASFLAGS)
@ -561,7 +565,7 @@ $(OBJDIR)/%.o : %.c
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
$(OBJDIR)/%.cpp.o : %.cpp
@echo
mkdir -p $(@D)
@echo $(MSG_COMPILING_CPP) $<
@ -628,3 +632,9 @@ $(shell mkdir $(OBJDIR) 2>/dev/null)
build elf hex eep lss sym coff extcoff \
clean clean_list debug gdb-config show_path \
program teensy dfu flip dfu-ee flip-ee dfu-start
# Print out the value of a make variable.
# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile
print-%:
@echo $* = $($*)

View file

@ -0,0 +1,30 @@
EEPROM Troubleshoot
===================
AVR Microcontroller
-------------------
`eeprom_show.hex` shows content of eeprom and `eeprom_wipe.hex` overwrite with 0xFF to erase eeprom.
Prebuilt firmware files for ATmega32u4 and ATmega32u2 are available.
- eeprom_show_atmega32u4.hex
- eeprom_wipe_atmega32u4.hex
- eeprom_show_atmega32u2.hex
- eeprom_wipe_atmega32u2.hex
Just flash the hex file and replug. Then, flash default application firmware again.
Check keyboard/eeprom_tool/ for source code.
AVR Arduino
-----------
For arduino boards(Leonardo, Pro Micro and Uno) you can use `eeprom_blank.hex` file also.
You can execute avrdude to erase eeprom like below:
avrdude -patmega32u4 -cavr109 -b57600 -Ueeprom:w:eeprom_blank1024.hex -P/dev/ttyACM0
avrdude -patmega328p -carduino -b115200 -Ueeprom:w:eeprom_blank1024.hex -P/dev/ttyACM0
Check this also. https://support.arduino.cc/hc/en-us/articles/5779192727068-Reset-your-board

View file

@ -0,0 +1,65 @@
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE
:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E
:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E
:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E
:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E
:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E
:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED
:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD
:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD
:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D
:00000001FF

View file

@ -0,0 +1,17 @@
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:00000001FF

View file

@ -0,0 +1,33 @@
:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
:1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30
:1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
:10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF
:10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF
:10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF
:10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F
:10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F
:1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F
:1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F
:00000001FF

View file

@ -0,0 +1,261 @@
:100000000C94A3000C94EB000C94EB000C94EB000C
:100010000C94EB000C94EB000C94EB000C94EB00B4
:100020000C94EB000C94EB000C94EB000C94BA05D0
:100030000C9448030C941F030C94EB000C94EB00FD
:100040000C94EB000C94EB000C94EB000C94F90274
:100050000C94EB000C94EB000C94EB000C94EB0074
:100060000C94EB000C94EB000C94EB000C94EB0064
:100070000C94EB000A002530325820000A25303459
:10008000583A2000656570726F6D3A002E000A4C78
:100090006F6F702073746172742E0A000A55534298
:1000A00020636F6E666967757265642E0A000A5474
:1000B0004D4B3A3630343735642F4C5546413A640F
:1000C00036613764660A000631FF0974A1010975BB
:1000D000150026FF00952075088102097615002677
:1000E000FF00952075089102C0090222000101005D
:1000F000A0320904000001030000000921110100E1
:1001000001222200070583032000011201100100D3
:10011000000008EDFEEEEE010001020001180345AB
:10012000004500500052004F004D00200054006F69
:10013000006F006C000000080354004D004B0000ED
:1001400000040309040011241FBECFEFD4E0DEBF7A
:10015000CDBF04B603FE28C080919F019091A001FD
:10016000A091A101B091A2018730904BA740B04B64
:10017000D9F410929F011092A0011092A101109247
:10018000A20114BE0FB6F894A89580916000886112
:1001900080936000109260000FBE109201081092D0
:1001A0000008E0E0F8E3099511E0A0E0B1E0E6E244
:1001B000F0E102C005900D92A630B107D9F721E019
:1001C000A6E0B1E001C01D92AF39B207E1F70E948D
:1001D00062060C9411080C940000FF93EF93E091D9
:1001E0000601F0910701309709F00995EF91FF9111
:1001F0000895FC018591803011F0EFDFFBCF089569
:10020000FF27E0E230E247FF0CC0419597FF09C0AD
:10021000EDE26095709580959095611D711D811D31
:10022000911D27FF02C0219530E350E2AA27660FF7
:10023000771F881F991FAA1FA41710F0A41B63958E
:100240005A95A9F7AA3008F0A95FA05DAF93F3957E
:10025000611571058105910541F7ED3211F4EF93B8
:10026000F395F21718F43F93F395FBCF8F91B5DF19
:10027000FA95E1F70895E991F9918591803021F09F
:10028000853219F0AADFF9CF089520E0E89455915E
:100290005532C1F3503311F4689455915A3348F4F0
:1002A000505390F3220F022E220F220F200D250F04
:1002B000F4CF0EF4219589919991533619F3533760
:1002C00029F1533559F1BC0188279927E8945C3608
:1002D00021F48991999168945591543639F446EFF7
:1002E0007EF077FF0DC08FEF9FEF0AC055374AE0D1
:1002F00039F0583540E121F0523642E009F00895D6
:10030000FF93EF937DDFEF91FF91B7CFFF93EF93D3
:10031000FC0181918030B9F360DFFBCFFF93EF9355
:1003200068DFF1CFDF93CF93CDB7DEB72596A3DF9C
:10033000CF91DF9108952FB7F89480919B01909110
:100340009C01A0919D01B0919E012FBF08958091C5
:10035000920187FF13C08091E80082FF06C0809160
:10036000E8008B778093E80004C0809190018111B0
:10037000F2CF0895809190018823D9F38091E8000D
:1003800080FFF8CF8091E8008E77ECCF982F909384
:10039000E900242F762F50E0891731F07091EC009E
:1003A0002091ED005091F00021FD07C09F5F953036
:1003B00071F78093E90081E008953091EB003E7F72
:1003C0003093EB003091ED003D7F3093ED003091A4
:1003D000EB0031603093EB007093EC002093ED0064
:1003E0005093F0002091EE0027FDE0CF80E00895CB
:1003F00080918801811113C09FB7F89440919B01AF
:1004000050919C0160919D0170919E019FBF443C61
:1004100059406105710518F081E0809388010895C5
:10042000EF92FF920F931F93CF93DF93D82F0FB6C6
:1004300007FE46C080919001843079F080910301DD
:1004400090E001962091050130E0822393232091D2
:1004500004012817190609F0C9C00E94F80181118A
:100460000FC08091030190E001962091050130E0DA
:1004700082239323209104012817190609F0B6C09E
:100480000E949B018C01C091E900CF708091EC002B
:1004900080FD37C080E0C82B83E08093E90085E0D1
:1004A000E82E8091EB0085FD08C08091EB0080FF75
:1004B00004C08091EE0087FD44C0CF70C093E90076
:1004C000E09103018E2F90E001962091050130E02C
:1004D00082239323209104012817190609F47EC072
:1004E0008091010190910201E80FF92FF11DD08355
:1004F000809103018F5F909105018923809303010F
:100500006DC080E8C8CFE0910101F0910201E80FD1
:10051000F11D90818F5F209105018223809304015A
:100520009093F1008091E80085FD0BC08091E80078
:1005300080FF07C08091E8008E778093E800E0920A
:1005400000018091040190910301981741F190916D
:10055000E80095FDD8CF80E029C01092F1002EC0B0
:100560008091030190E001962091050130E0822303
:100570009323209104012817190609F09ECFF090CB
:100580000001FF2009F499CF0E949B018017910779
:1005900009F487CFFA94F09200018C0182CF809108
:1005A000E80085FFD8CFD093F10081E09091F20070
:1005B000992379F09091E80090FF0BC09091E800AA
:1005C00095FDCBCF9091E8009E779093E800E09264
:1005D0000001882329F2CF70C093E90080E0DF9109
:1005E000CF911F910F91FF90EF900895E09103013B
:1005F00077CF78941F920F920FB60F9211248F939A
:100600009F93AF93BF9380919B0190919C01A09188
:100610009D01B0919E010196A11DB11D80939B018A
:1006200090939C01A0939D01B0939E01BF91AF91C7
:100630009F918F910F900FBE0F901F9018951F9252
:100640000F920FB60F9211248F939F93AF93BF9386
:1006500080919A01811113C080919B0190919C011E
:10066000A0919D01B0919E014196A11DB11D809365
:100670009B0190939C01A0939D01B0939E01BF911B
:10068000AF919F918F910F900FBE0F901F90189573
:100690001F920F920FB60F9211240F931F932F9357
:1006A0003F934F935F936F937F938F939F93AF93FA
:1006B000BF93EF93FF93CF93DF93CDB7DEB7AA97A6
:1006C000DEBFCDBF1091E9001F708091EC0080FF6C
:1006D0002FC080E8182B1092E9008091F000877FEE
:1006E0008093F0007894E2E9F1E08AE991E02091CA
:1006F000F10021938E179F07D1F78091E80083FFC7
:1007000047C080919201909193019A3008F040C0C7
:10071000E92FF0E0E257FC4F0C940B089A03C0035A
:10072000C803C003C8033B045D04C8038C059905D6
:1007300080E0D0CF803889F0823851F580919601E1
:100740008F70853028F58093E9008091EB0085FB60
:10075000882780F91092E90006C080918E0190915F
:100760008F01911182609091E800977F9093E8004B
:100770008093F1001092F1008091E8008E7749C0DB
:10078000282F2D7F29F48823B1F1823009F446C047
:100790008091E80083FF0AC08091E800877F809302
:1007A000E8008091EB0080628093EB001092E900FA
:1007B0008091F00088608093F0001F701093E90032
:1007C000AA960FB6F894DEBF0FBECDBFDF91CF91D2
:1007D000FF91EF91BF91AF919F918F917F916F9119
:1007E0005F914F913F912F911F910F910F900FBEED
:1007F0000F901F90189580919401813049F69330A5
:1008000009F080E080938F011092E9008091E80068
:10081000877F8093E8000E94A701BACF809194015E
:100820008111F2CF809196018F702FEF280F243025
:1008300008F0AECF8093E9002091EB0020FFE4CFD9
:10084000933031F48091EB0080628093EB00DCCF39
:100850009091EB0090619093EB0021E030E001C0BB
:10086000220F8A95EAF72093EA001092EA0080911D
:10087000EB008860EACF81118BCF009194010F7754
:100880008091E3008078802B8093E3008091E800E2
:10089000877F8093E8000E94A7018091E80080FF95
:1008A000FCCF8091E30080688093E30083E0011136
:1008B00001C082E0809390016BCF8058823008F0B5
:1008C00067CF20919401309195012C3D83E038074A
:1008D00009F07AC083E08A838AE289834FB7F8946B
:1008E000DE01139620E03EE051E2E32FF0E050936A
:1008F0005700E49120FF03C0E295EF703F5FEF7077
:100900008E2F90E0EA30C0F0C7968D939D932F5FB5
:10091000243159F74FBF8091E800877F8093E8002A
:1009200080919801909199018A32910508F049C00F
:1009300040E0FE01319626C0C096E7CF209190019D
:10094000222391F1253081F12091E80023FD2CC074
:100950002091E80022FD1AC02091E80020FF12C07B
:100960002091F20030E0009719F02830310510F1A5
:1009700041E02830310509F040E02091E8002E7771
:100980002093E8000097D1F64111D8CF8091E8007C
:1009900082FD0AC080919001882331F0853021F0DA
:1009A0008091E80083FFF2CF8091E8008B778093FD
:1009B000E800EECE41914093F10001972F5F3F4F49
:1009C000D2CF8AE290E0B4CF409196015091970146
:1009D000832F99278330910509F43EC080F581303B
:1009E000910509F465C0029709F0D2CE82E290E049
:1009F000E9EEF0E02091E800277F2093E8002091C5
:100A00009801309199018217930708F49C0140E006
:100A10002115310509F051C041114FC08091E80006
:100A200082FDC2CF80919001882309F4BDCF85302B
:100A300009F4BACF8091E80083FFF0CFB5CF8132BF
:100A4000910571F18232910509F0A2CE452B09F092
:100A50009FCEE7ECF0E0CECF332721303105C1F057
:100A600060F02230310509F093CEEDE1F1E0E49140
:100A70008E2F90E0EDE1F1E007C0E1E4F1E0E491D8
:100A80008E2F90E0E1E4F1E0009709F481CEB2CF3F
:100A9000E7E3F1E0E4918E2F90E0E7E3F1E0F4CFBB
:100AA000452B09F075CE89E090E0EBEFF0E0A2CFA6
:100AB00082E190E0EBE0F1E09DCF8091900188230E
:100AC00009F472CF853009F46FCF8091E80083FD7F
:100AD0006BCF8091E80082FDA1CF8091E80080FF7C
:100AE00097CF8091F20090E02115310519F0883000
:100AF000910550F041E0089709F040E08091E8004E
:100B00008E778093E80084CF44914093F100319632
:100B1000215031090196E8CF803809F039CE809113
:100B2000E800877F8093E800809191018093F10035
:100B300023CE81112DCE00919401023008F028CEF1
:100B40008091E800877F8093E800009391010E94E4
:100B5000A701002349F084E08093900146E261EC14
:100B600083E00E94C60114CE8091E30087FDF3CF9D
:100B700081E0F2CF1F920F920FB60F9211242F93A4
:100B80003F934F935F936F937F938F939F93AF9315
:100B9000BF93EF93FF938091E10082FF09C08091A2
:100BA000E20082FF05C08091E1008B7F8093E1002D
:100BB0008091E10080FF17C08091E20080FF13C0A8
:100BC0008091E2008E7F8093E2008091E20080615C
:100BD0008093E2008091D80080628093D80019BC95
:100BE00085E0809390018091E10084FF27C080918F
:100BF000E20084FF23C084E089BD86E089BD09B49A
:100C000000FEFDCF8091D8008F7D8093D800809129
:100C1000E1008F7E8093E1008091E2008F7E8093DF
:100C2000E2008091E20081608093E2008091910176
:100C3000882309F43FC084E0809390018091E10013
:100C400083FF27C08091E20083FF23C08091E100F1
:100C5000877F8093E10082E0809390011092910160
:100C60008091E1008E7F8093E1008091E2008E7F91
:100C70008093E2008091E20080618093E20042E094
:100C800060E080E00E94C6018091F000886080935F
:100C9000F000FF91EF91BF91AF919F918F917F9164
:100CA0006F915F914F913F912F910F900FBE0F90D9
:100CB0001F9018958091E30087FD02C081E0BCCFB2
:100CC00083E0BACF84B7877F84BF0FB6F894A89526
:100CD00080916000886180936000109260000FBE78
:100CE00080E890E00FB6F8948093610090936100E3
:100CF0000FBE80E192E090930701809306018EEA97
:100D000090E00E94F9001092E2001092E1008091C0
:100D1000E00081608093E0008091D8008F7780931D
:100D2000D80019BC809163008160809363001092A9
:100D30008901809163008E7F8093630081E08093BE
:100D400089011092E2001092E1008091D8008F7723
:100D50008093D8008091D80080688093D8008091DB
:100D6000D8008F7D8093D80084E089BD86E089BD5E
:100D700009B400FEFDCF10929001109291011092E3
:100D80008F0110928E0142E060E080E00E94C60177
:100D90008091E1008E7F8093E1008091E20081608C
:100DA0008093E2008091E20088608093E20080916D
:100DB000E0008E7F8093E000789482E084BD93E031
:100DC00095BD9AEF97BD80936E008091900184301D
:100DD000E1F70E94F8018823C1F38CE990E00E94BA
:100DE000F90084E890E09F938F930E9492010F9006
:100DF0000F90D0E0C0E03CE7E32E30E0F32E06E7B2
:100E000010E0CE018F709927892B51F4DF93CF9397
:100E1000FF92EF920E9492010F900F900F900F900F
:100E2000CE010E94EF071F928F931F930F930E9492
:100E3000920121960F900F900F900F90C11584E0B2
:100E4000D807F9F684E790E09F938F930E94920170
:100E50008EE890E00E94F9000F900F9083E0D82E6A
:100E600008EE13E0CCE8D0E098E1E92EF12C20E484
:100E7000C22E80919001853009F44CC00E949B01E4
:100E80005C0180918A0190918B01A816B90661F0EE
:100E9000C501B8010E94F707892B31F4DF93CF9386
:100EA0000E9492010F900F90B0928B01A0928A0144
:100EB0002091E4003091E50080918C0190918D01AA
:100EC00028173907B1F28091E4009091E5009093E2
:100ED0008D0180938C010E94F801882351F280914A
:100EE0009001843031F68091E9008F709091EC0090
:100EF00090FD37C090E0892BD092E9009091EB00F3
:100F000090FF04C09091EE0097FD49C08F708093D0
:100F1000E900AFCF80919001843009F4AACF1092FC
:100F20009A010FB6F894A895E09260000FBEC092A7
:100F3000600083B7817F846083BF83B7816083BF94
:100F40007894889583B78E7F83BF0FB6F894A89561
:100F500080916000886180936000109260000FBEF5
:100F600088CF90E8C8CFE0910101F0910201E90F2C
:100F7000F11D20819F5F309105019323909304011F
:100F80002093F1009091E80095FD09C09091E80050
:100F900090FF05C09091E8009E779093E8009091B3
:100FA000040120910301291721F02091E80025FD7B
:100FB000DACF9091F200992309F4A8CF9091E8003C
:100FC00090FFA4CF9091E80095FD06C09091E800B5
:100FD0009E779093E8009ACF1092F100F3CFF999A1
:100FE000FECF92BD81BDF89A992780B50895AA1BBE
:100FF000BB1B51E107C0AA1FBB1FA617B70710F004
:10100000A61BB70B881F991F5A95A9F78095909535
:10101000BC01CD010895EE0FFF1F0590F491E02D66
:061020000994F894FFCFD3
:0610260005080100007F37
:00000001FF

View file

@ -0,0 +1,277 @@
:100000000C94BF000C9407010C9407010C94070199
:100010000C9407010C9407010C9407010C94070140
:100020000C9407010C9407010C9462060C94E803ED
:100030000C94BF030C9407010C9407010C94070166
:100040000C9407010C9407010C9407010C94070110
:100050000C9407010C9499030C9407010C9407016C
:100060000C9407010C9407010C9407010C940701F0
:100070000C9407010C9407010C9407010C940701E0
:100080000C9407010C9407010C9407010C940701D0
:100090000C9407010C9407010C9407010C940701C0
:1000A0000C9407010C9407010C9407010A002530F9
:1000B000325820000A253034583A200065657072A5
:1000C0006F6D3A002E000A4C6F6F7020737461726E
:1000D000742E0A000A55534220636F6E6669677575
:1000E0007265642E0A000A544D4B3A363034373567
:1000F000642F4C5546413A6436613764660A0006FF
:1001000031FF0974A1010975150026FF00952075BE
:100110000881020976150026FF00952075089102D6
:10012000C009022200010100A032090400000103FD
:1001300000000009211101000122220007058303AC
:100140002000011201100100000008EDFEEEEE019A
:100150000001020001180345004500500052004F05
:10016000004D00200054006F006F006C000000087C
:100170000354004D004B0000000403090400112447
:100180001FBECFEFDAE0DEBFCDBF04B603FE28C04E
:1001900080911F0290912002A0912102B091220231
:1001A0008730904BA740B04BD9F410921F021092A9
:1001B0002002109221021092220214BE0FB6F8946F
:1001C000A895809160008861809360001092600023
:1001D0000FBE1092010810920008E0E0F8E30995C4
:1001E00011E0A0E0B1E0E6E2F1E102C005900D927D
:1001F000A630B107D9F722E0A6E0B1E001C01D9218
:10020000AF31B207E1F70E9433070C9491080C94C8
:100210000000FF93EF93E0910601F0910701309702
:1002200009F00995EF91FF910895FC0185918030C7
:1002300011F0EFDFFBCF0895FF27E0E230E247FF48
:100240000CC0419597FF09C0EDE2609570958095CF
:100250009095611D711D811D911D27FF02C0219583
:1002600030E350E2AA27660F771F881F991FAA1F45
:10027000A41710F0A41B63955A95A9F7AA3008F0AB
:10028000A95FA05DAF93F395611571058105910597
:1002900041F7ED3211F4EF93F395F21718F43F9311
:1002A000F395FBCF8F91B5DFFA95E1F70895E991CA
:1002B000F9918591803021F0853219F0AADFF9CFCC
:1002C000089520E0E89455915532C1F3503311F46C
:1002D000689455915A3348F4505390F3220F022EEC
:1002E000220F220F200D250FF4CF0EF421958991B6
:1002F0009991533619F3533729F1533559F1BC010C
:1003000088279927E8945C3621F48991999168941B
:100310005591543639F446EF7EF077FF0DC08FEFDC
:100320009FEF0AC055374AE039F0583540E121F0D7
:10033000523642E009F00895FF93EF937DDFEF918D
:10034000FF91B7CFFF93EF93FC0181918030B9F318
:1003500060DFFBCFFF93EF9368DFF1CFDF93CF93A5
:10036000CDB7DEB72596A3DFCF91DF9108952FB7E4
:10037000F89480911B0290911C02A0911D02B091F3
:100380001E022FBF0895E8EDF0E080818E7F80830C
:100390001092E2001092DA001092E100A0EEB0E0BC
:1003A0008C9181608C9380818F77808319BCA7EDBD
:1003B000B0E08C918E7F8C9380818F7E80831092B1
:1003C0000D0208958091120287FF13C08091E8000A
:1003D00082FF06C08091E8008B778093E80004C01C
:1003E000809110028111F2CF08958091100288232C
:1003F000D9F38091E80080FFF8CF8091E8008E77F4
:10040000ECCF982F9093E900242F762F50E0891796
:1004100031F07091EC002091ED005091F00021FD41
:1004200007C09F5F973071F78093E90081E00895DE
:100430003091EB003E7F3093EB003091ED003D7F3B
:100440003093ED003091EB0031603093EB0070930E
:10045000EC002093ED005093F0002091EE0027FD7A
:10046000E0CF80E00895CF92DF92EF92FF920F935A
:100470001F93CF93DF93C8EDD0E088818F7E888370
:10048000E7EDF0E080818160808384E082BF81E0DD
:1004900080930D0288818E7F888302EE10E0F80140
:1004A00010821092DA0081EEC82ED12CF601108253
:1004B00088818F77888388818068888388818F7D11
:1004C000888319BC109210021092110210920F0230
:1004D00010920E0290EEE92EF12CF70180818B7FB5
:1004E000808388818160888342E060E080E00E94B0
:1004F0000102F60180818E7F8083F8018081816016
:100500008083808188608083F70180818E7F8083F3
:10051000888180618883DF91CF911F910F91FF9037
:10052000EF90DF90CF90089580910802811113C061
:100530009FB7F89440911B0250911C0260911D02DC
:1005400070911E029FBF443C59406105710518F02F
:1005500081E0809308020895EF92FF920F931F931A
:10056000CF93DF93D82F0FB607FE46C080911002BD
:10057000843079F08091030190E00196209105018B
:1005800030E082239323209104012817190609F0F3
:10059000CDC00E94940281110FC08091030190E0B0
:1005A00001962091050130E08223932320910401DC
:1005B0002817190609F0BAC00E94B7018C01C09132
:1005C000E900CF708091EC0080FD37C080E0C82B3F
:1005D00083E08093E90085E0E82E8091EB0085FDC3
:1005E00008C08091EB0080FF04C08091EE0087FD81
:1005F00044C0CF70C093E900E09103018E2F90E0DA
:1006000001962091050130E082239323209104017B
:100610002817190609F482C0809101019091020106
:10062000E80FF92FF11DD083809103018F5F909126
:10063000050189238093030171C080E8C8CFE09150
:100640000101F0910201E80FF11D90818F5F20916F
:1006500005018223809304019093F1008091E800CA
:1006600085FD0BC08091E80080FF07C08091E80005
:100670008E778093E800E0920001809104019091D0
:100680000301981741F19091E80095FDD8CF80E0E3
:1006900029C01092F10032C08091030190E00196D0
:1006A0002091050130E08223932320910401281733
:1006B000190609F09ECFF0900001FF2009F499CFB0
:1006C0000E94B7018017910709F487CFFA94F0923E
:1006D00000018C0182CF8091E80085FFD8CFD093B4
:1006E000F10081E02091F3009091F200322F292F48
:1006F000232B79F09091E80090FF0BC09091E800D7
:1007000095FDC7CF9091E8009E779093E800E09226
:100710000001882309F2CF70C093E90080E0DF91E7
:10072000CF911F910F91FF90EF900895E0910301F9
:1007300073CF78941F920F920FB60F9211248F935C
:100740009F93AF93BF9380911B0290911C02A09145
:100750001D02B0911E020196A11DB11D80931B02C6
:1007600090931C02A0931D02B0931E02BF91AF9103
:100770009F918F910F900FBE0F901F9018951F9211
:100780000F920FB60F9211248F939F93AF93BF9345
:1007900080911A02811113C080911B0290911C025A
:1007A000A0911D02B0911E024196A11DB11D809322
:1007B0001B0290931C02A0931D02B0931E02BF91D6
:1007C000AF919F918F910F900FBE0F901F90189532
:1007D0001F920F920FB60F9211240F931F932F9316
:1007E0003F934F935F936F937F938F939F93AF93B9
:1007F000BF93EF93FF93CF93DF93CDB7DEB7AA9765
:10080000DEBFCDBF1091E9001F708091EC0080FF2A
:100810002FC080E8182B1092E9008091F000877FAC
:100820008093F0007894E2E1F2E08AE192E0209196
:10083000F10021938E179F07D1F78091E80083FF85
:1008400047C080911202909113029A3008F040C084
:10085000E92FF0E0E25DFB4F0C948B083A04600452
:10086000680460046804DB04FD046804340641067F
:1008700080E0D0CF803889F0823851F5809116021F
:100880008F70873028F58093E9008091EB0085FB1D
:10089000882780F91092E90006C080910E0290919D
:1008A0000F02911182609091E800977F9093E80089
:1008B0008093F1001092F1008091E8008E7749C09A
:1008C000282F2D7F29F48823B1F1823009F446C006
:1008D0008091E80083FF0AC08091E800877F8093C1
:1008E000E8008091EB0080628093EB001092E900B9
:1008F0008091F00088608093F0001F701093E900F1
:10090000AA960FB6F894DEBF0FBECDBFDF91CF9190
:10091000FF91EF91BF91AF919F918F917F916F91D7
:100920005F914F913F912F911F910F910F900FBEAB
:100930000F901F90189580911402813049F69330E2
:1009400009F080E080930F021092E9008091E800A6
:10095000877F8093E8000E94E201BACF8091140261
:100960008111F2CF809116028F702FEF280F263061
:1009700008F0AECF8093E9002091EB0020FFE4CF98
:10098000933031F48091EB0080628093EB00DCCFF8
:100990009091EB0090619093EB0021E030E001C07A
:1009A000220F8A95EAF72093EA001092EA008091DC
:1009B000EB008860EACF81118BCF009114020F7792
:1009C0008091E3008078802B8093E3008091E800A1
:1009D000877F8093E8000E94E2018091E80080FF19
:1009E000FCCF8091E30080688093E30083E00111F5
:1009F00001C082E0809310026BCF8058823008F0F3
:100A000067CF20911402309115022C3D83E0380706
:100A100009F07EC083E08A838AE289834FB7F89425
:100A2000DE01139620E03EE051E2E32FF0E0509328
:100A30005700E49120FF03C0E295EF703F5FEF7035
:100A40008E2F90E0EA30C0F0C7968D939D932F5F74
:100A5000243159F74FBF8091E800877F8093E800E9
:100A600080911802909119028A32910508F04DC0C8
:100A700040E0FE0131962AC0C096E7CF20911002D7
:100A80002223B1F12530A1F12091E80023FD30C0EF
:100A90002091E80022FD1EC02091E80020FF16C032
:100AA0002091F3003091F20023273227232700976B
:100AB00019F02830310510F141E02830310509F0F6
:100AC00040E02091E8002E772093E8000097B1F6EF
:100AD0004111D4CF8091E80082FD0AC080911002BC
:100AE000882331F0853021F08091E80083FFF2CF38
:100AF0008091E8008B778093E800EACE41914093A3
:100B0000F10001972F5F3F4FD2CF8AE290E0B0CF44
:100B10004091160250911702832F99278330910537
:100B200009F43EC080F58130910509F465C0029753
:100B300009F0CECE82E290E0E1E2F1E02091E8001F
:100B4000277F2093E8002091180230911902821724
:100B5000930708F49C0140E02115310509F051C0CC
:100B600041114FC08091E80082FDC2CF80911002F8
:100B7000882309F4BDCF853009F4BACF8091E8000D
:100B800083FFF0CFB5CF8132910571F182329105AB
:100B900009F09ECE452B09F09BCEEFEFF0E0CECFD3
:100BA000332721303105C1F060F02230310509F0E2
:100BB0008FCEE5E5F1E0E4918E2F90E0E5E5F1E000
:100BC00007C0E9E7F1E0E4918E2F90E0E9E7F1E07A
:100BD000009709F47DCEB2CFEFE6F1E0E4918E2FDD
:100BE00090E0EFE6F1E0F4CF452B09F071CE89E01B
:100BF00090E0E3E3F1E0A2CF82E190E0E3E4F1E012
:100C00009DCF80911002882309F472CF853009F4BA
:100C10006FCF8091E80083FD6BCF8091E80082FD6B
:100C2000A1CF8091E80080FF97CF8091F300909151
:100C3000F2008927982789272115310519F0883076
:100C4000910550F041E0089709F040E08091E800FC
:100C50008E778093E80080CF44914093F1003196E5
:100C6000215031090196E8CF803809F031CE8091CA
:100C7000E800877F8093E800809111028093F10063
:100C80001BCE811125CE00911402023008F020CE37
:100C90008091E800877F8093E800009311020E9412
:100CA000E201002349F084E08093100246E261EC07
:100CB00083E00E9401020CCE8091E30087FDF3CF18
:100CC00081E0F2CF1F920F920FB60F9211242F9353
:100CD0003F934F935F936F937F938F939F93AF93C4
:100CE000BF93EF93FF938091E10082FF09C0809151
:100CF000E20082FF05C08091E1008B7F8093E100DC
:100D00008091DA0080FF1FC08091D80080FF1BC057
:100D10008091DA008E7F8093DA008091D90080FF85
:100D200094C080E189BD82E189BD09B400FEFDCF98
:100D300081E08093100280910D02811104C00E9415
:100D4000C3010E9433028091E10080FF17C08091AF
:100D5000E20080FF13C08091E2008E7F8093E2006A
:100D60008091E20080618093E2008091D8008062EF
:100D70008093D80019BC85E0809310028091E10037
:100D800084FF27C08091E20084FF23C080E189BDF9
:100D900082E189BD09B400FEFDCF8091D8008F7D2E
:100DA0008093D8008091E1008F7E8093E100809154
:100DB000E2008F7E8093E2008091E2008160809368
:100DC000E20080911102882309F445C084E08093F9
:100DD00010028091E10083FF27C08091E20083FF31
:100DE00023C08091E100877F8093E10082E08093BF
:100DF0001002109211028091E1008E7F8093E10039
:100E00008091E2008E7F8093E2008091E200806119
:100E10008093E20042E060E080E00E940102809165
:100E2000F00088608093F000FF91EF91BF91AF9147
:100E30009F918F917F916F915F914F913F912F91F2
:100E40000F900FBE0F901F90189519BC10921002B2
:100E500010920D0278CF8091E30087FD02C081E0FF
:100E6000B6CF83E0B4CF84B7877F84BF0FB6F89442
:100E7000A895809160008861809360001092600066
:100E80000FBE80E890E00FB6F894809361009093D5
:100E900061000FBE8CEA92E09093070180930601F7
:100EA00086EE90E00E9415010E94C3010E94330269
:100EB000789482E084BD93E095BD9AEF97BD8093CE
:100EC0006E00809110028430E1F70E949402882322
:100ED000C1F384ED90E00E9415018CEB90E09F93AC
:100EE0008F930E94AE010F900F90D0E0C0E034EBE2
:100EF000E32E30E0F32E0EEA10E0CE018F7099273A
:100F0000892B51F4DF93CF93FF92EF920E94AE01B1
:100F10000F900F900F900F90CE010E946F081F92BC
:100F20008F931F930F930E94AE0121960F900F9005
:100F30000F900F90C11584E0D807F9F68CEA90E085
:100F40009F938F930E94AE0186EC90E00E94150162
:100F50000F900F9083E0D82E08EE13E0C4ECD0E0A1
:100F600098E1E92EF12C20E4C22E80911002853008
:100F700009F44CC00E94B7015C0180910902909174
:100F80000A02A816B90661F0C501B8010E947708E7
:100F9000892B31F4DF93CF930E94AE010F900F9015
:100FA000B0920A02A09209022091E4003091E5007B
:100FB00080910B0290910C0228173907B1F28091B1
:100FC000E4009091E50090930C0280930B020E9444
:100FD0009402882351F280911002843031F680917E
:100FE000E9008F709091EC0090FD37C090E0892B64
:100FF000D092E9009091EB0090FF04C09091EE0038
:1010000097FD49C08F708093E900AFCF80911002A7
:10101000843009F4AACF10921A020FB6F894A8955A
:10102000E09260000FBEC092600083B7817F846051
:1010300083BF83B7816083BF7894889583B78E7FA1
:1010400083BF0FB6F894A895809160008861809363
:101050006000109260000FBE88CF90E8C8CFE0918A
:101060000101F0910201E90FF11D20819F5F309194
:1010700005019323909304012093F1009091E800DF
:1010800095FD09C09091E80090FF05C09091E8009F
:101090009E779093E8009091040120910301291715
:1010A00021F02091E80025FDDACF2091F300909106
:1010B000F200322F292F232B09F4A4CF9091E800BE
:1010C00090FFA0CF9091E80095FD06C09091E800B8
:1010D0009E779093E80096CF1092F100F3CFF999A4
:1010E000FECF92BD81BDF89A992780B50895AA1BBD
:1010F000BB1B51E107C0AA1FBB1FA617B70710F003
:10110000A61BB70B881F991F5A95A9F78095909534
:10111000BC01CD010895EE0FFF1F0590F491E02D65
:061120000994F894FFCFD2
:061126000508010000FFB6
:00000001FF

View file

@ -0,0 +1,274 @@
:100000000C94B0000C94F8000C94F8000C94F800D8
:100010000C94F8000C94F8000C94F8000C94F80080
:100020000C94F8000C94F8000C94F8000C940D0655
:100030000C949B030C9472030C94F8000C94F8003D
:100040000C94F8000C94F8000C94F8000C944C03F9
:100050000C94F8000C94F8000C94F8000C94F80040
:100060000C94F8000C94F8000C94F8000C94F80030
:100070000C94F8000A002530325820000A2530344C
:10008000583A2000656570726F6D3A000A0025309D
:1000900034583A2000656570726F6D20776970651D
:1000A0003A20000A000A002E000A4C6F6F7020737D
:1000B000746172742E0A000A55534220636F6E6693
:1000C0006967757265642E0A000A544D4B3A3630E2
:1000D000343735642F4C5546413A6436613764668F
:1000E0000A000631FF0974A1010975150026FF00F9
:1000F0009520750881020976150026FF0095207568
:10010000089102C009022200010100A03209040086
:100110000001030000000921110100012222000753
:100120000583032000011201100100000008EDFE0C
:10013000EEEE0100010200011803450045005000E9
:1001400052004F004D00200054006F006F006C0003
:100150000000080354004D004B0000000403090494
:1001600011241FBECFEFD4E0DEBFCDBF04B603FE27
:1001700028C080919F019091A001A091A101B09110
:10018000A2018730904BA740B04BD9F410929F0149
:100190001092A0011092A1011092A20114BE0FB6FC
:1001A000F894A89580916000886180936000109217
:1001B00060000FBE1092010810920008E0E0F8E322
:1001C000099511E0A0E0B1E0E6EFF0E102C0059092
:1001D0000D92A630B107D9F721E0A6E0B1E001C049
:1001E0001D92AF39B207E1F70E94B5060C94790869
:1001F0000C940000FF93EF93E0910601F09107014A
:10020000309709F00995EF91FF910895FC018591D0
:10021000803011F0EFDFFBCF0895FF27E0E230E2FE
:1002200047FF0CC0419597FF09C0EDE260957095BE
:1002300080959095611D711D811D911D27FF02C044
:10024000219530E350E2AA27660F771F881F991F78
:10025000AA1FA41710F0A41B63955A95A9F7AA30FA
:1002600008F0A95FA05DAF93F39561157105810555
:10027000910541F7ED3211F4EF93F395F21718F46D
:100280003F93F395FBCF8F91B5DFFA95E1F7089592
:10029000E991F9918591803021F0853219F0AADF3A
:1002A000F9CF089520E0E89455915532C1F35033C9
:1002B00011F4689455915A3348F4505390F3220F37
:1002C000022E220F220F200D250FF4CF0EF42195C0
:1002D00089919991533619F3533729F1533559F1CF
:1002E000BC0188279927E8945C3621F4899199917B
:1002F00068945591543639F446EF7EF077FF0DC07F
:100300008FEF9FEF0AC055374AE039F0583540E18A
:1003100021F0523642E009F00895FF93EF937DDF1C
:10032000EF91FF91B7CFFF93EF93FC018191803064
:10033000B9F360DFFBCFFF93EF9368DFF1CFDF937B
:10034000CF93CDB7DEB72596A3DFCF91DF91089588
:100350002FB7F89480919B0190919C01A0919D01F1
:10036000B0919E012FBF08958091920187FF13C025
:100370008091E80082FF06C08091E8008B7780932F
:10038000E80004C0809190018111F2CF089580911E
:1003900090018823D9F38091E80080FFF8CF809105
:1003A000E8008E77ECCF982F9093E900242F762FDA
:1003B00050E0891731F07091EC002091ED005091E0
:1003C000F00021FD07C09F5F953071F78093E90031
:1003D00081E008953091EB003E7F3093EB00309147
:1003E000ED003D7F3093ED003091EB0031603093B4
:1003F000EB007093EC002093ED005093F0002091FF
:10040000EE0027FDE0CF80E0089580918801811102
:1004100013C09FB7F89440919B0150919C0160914B
:100420009D0170919E019FBF443C5940610571053B
:1004300018F081E0809388010895EF92FF920F9366
:100440001F93CF93DF93D82F0FB607FE46C080913E
:100450009001843079F08091030190E00196209121
:10046000050130E082239323209104012817190607
:1004700009F0C9C00E94050281110FC080910301DB
:1004800090E001962091050130E082239323209192
:1004900004012817190609F0B6C00E94A8018C01B2
:1004A000C091E900CF708091EC0080FD37C080E002
:1004B000C82B83E08093E90085E0E82E8091EB0073
:1004C00085FD08C08091EB0080FF04C08091EE00A4
:1004D00087FD44C0CF70C093E900E09103018E2FE7
:1004E00090E001962091050130E082239323209132
:1004F00004012817190609F47EC08091010190912A
:100500000201E80FF92FF11DD083809103018F5F65
:10051000909105018923809303016DC080E8C8CFC5
:10052000E0910101F0910201E80FF11D90818F5FD0
:10053000209105018223809304019093F100809122
:10054000E80085FD0BC08091E80080FF07C0809126
:10055000E8008E778093E800E0920001809104012A
:1005600090910301981741F19091E80095FDD8CF43
:1005700080E029C01092F1002EC08091030190E02C
:1005800001962091050130E08223932320910401FC
:100590002817190609F09ECFF0900001FF2009F4FA
:1005A00099CF0E94A8018017910709F487CFFA9488
:1005B000F09200018C0182CF8091E80085FFD8CFB6
:1005C000D093F10081E09091F200992379F090911D
:1005D000E80090FF0BC09091E80095FDCBCF909183
:1005E000E8009E779093E800E0920001882329F2CA
:1005F000CF70C093E90080E0DF91CF911F910F9100
:10060000FF90EF900895E091030177CFEF92FF9272
:100610000F931F93CF93DF9384E890E09F938F9382
:100620000E949F010F900F90D0E0C0E08CE7E82E71
:1006300080E0F82E06E710E0CE018F709927892B15
:1006400051F4DF93CF93FF92EF920E949F010F909E
:100650000F900F900F90CE010E9449081F928F9328
:100660001F930F930E949F0121960F900F900F9060
:100670000F90C11584E0D807F9F684E790E09F93C6
:100680008F930E949F010F900F90DF91CF911F9148
:100690000F91FF90EF90089578941F920F920FB6EC
:1006A0000F9211248F939F93AF93BF9380919B01DF
:1006B00090919C01A0919D01B0919E010196A11D78
:1006C000B11D80939B0190939C01A0939D01B093D9
:1006D0009E01BF91AF919F918F910F900FBE0F9090
:1006E0001F9018951F920F920FB60F9211248F939F
:1006F0009F93AF93BF9380919A01811113C0809112
:100700009B0190919C01A0919D01B0919E01419609
:10071000A11DB11D80939B0190939C01A0939D010D
:10072000B0939E01BF91AF919F918F910F900FBE9B
:100730000F901F9018951F920F920FB60F921124D1
:100740000F931F932F933F934F935F936F937F93D9
:100750008F939F93AF93BF93EF93FF93CF93DF93C9
:10076000CDB7DEB7AA97DEBFCDBF1091E9001F70ED
:100770008091EC0080FF2FC080E8182B1092E900D8
:100780008091F000877F8093F0007894E2E9F1E0B7
:100790008AE991E02091F10021938E179F07D1F70C
:1007A0008091E80083FF47C080919201909193016E
:1007B0009A3008F040C0E92FF0E0EF51FC4F0C9464
:1007C0007308ED0313041B0413041B048E04B0040C
:1007D0001B04DF05EC0580E0D0CF803889F082383B
:1007E00051F5809196018F70853028F58093E9004E
:1007F0008091EB0085FB882780F91092E90006C004
:1008000080918E0190918F01911182609091E8000A
:10081000977F9093E8008093F1001092F10080910F
:10082000E8008E7749C0282F2D7F29F48823B1F165
:10083000823009F446C08091E80083FF0AC08091AD
:10084000E800877F8093E8008091EB0080628093CE
:10085000EB001092E9008091F00088608093F00036
:100860001F701093E900AA960FB6F894DEBF0FBE72
:10087000CDBFDF91CF91FF91EF91BF91AF919F914C
:100880008F917F916F915F914F913F912F911F9128
:100890000F910F900FBE0F901F90189580919401AB
:1008A000813049F6933009F080E080938F011092F7
:1008B000E9008091E800877F8093E8000E94B401FE
:1008C000BACF809194018111F2CF809196018F70FF
:1008D0002FEF280F243008F0AECF8093E90020914D
:1008E000EB0020FFE4CF933031F48091EB00806285
:1008F0008093EB00DCCF9091EB0090619093EB0044
:1009000021E030E001C0220F8A95EAF72093EA0047
:100910001092EA008091EB008860EACF81118BCFC2
:10092000009194010F778091E3008078802B809371
:10093000E3008091E800877F8093E8000E94B40183
:100940008091E80080FFFCCF8091E3008068809375
:10095000E30083E0011101C082E0809390016BCF3E
:100960008058823008F067CF209194013091950132
:100970002C3D83E0380709F07AC083E08A838AE25D
:1009800089834FB7F894DE01139620E03EE051E2F0
:10099000E32FF0E050935700E49120FF03C0E2956D
:1009A000EF703F5FEF708E2F90E0EA30C0F0C79697
:1009B0008D939D932F5F243159F74FBF8091E800AD
:1009C000877F8093E80080919801909199018A3205
:1009D000910508F049C040E0FE01319626C0C0965E
:1009E000E7CF20919001222391F1253081F12091D0
:1009F000E80023FD2CC02091E80022FD1AC02091C0
:100A0000E80020FF12C02091F20030E0009719F0BA
:100A10002830310510F141E02830310509F040E07F
:100A20002091E8002E772093E8000097D1F641113D
:100A3000D8CF8091E80082FD0AC080919001882380
:100A400031F0853021F08091E80083FFF2CF809172
:100A5000E8008B778093E800EECE41914093F1005F
:100A600001972F5F3F4FD2CF8AE290E0B4CF409101
:100A7000960150919701832F99278330910509F4AE
:100A80003EC080F58130910509F465C0029709F0F8
:100A9000D2CE82E290E0E4E0F1E02091E800277F0E
:100AA0002093E800209198013091990182179307D3
:100AB00008F49C0140E02115310509F051C04111B5
:100AC0004FC08091E80082FDC2CF809190018823C1
:100AD00009F4BDCF853009F4BACF8091E80083FFD7
:100AE000F0CFB5CF8132910571F18232910509F0D5
:100AF000A2CE452B09F09FCEE2EEF0E0CECF332719
:100B000021303105C1F060F02230310509F093CE7B
:100B1000E8E3F1E0E4918E2F90E0E8E3F1E007C034
:100B2000ECE5F1E0E4918E2F90E0ECE5F1E0009748
:100B300009F481CEB2CFE2E5F1E0E4918E2F90E0AE
:100B4000E2E5F1E0F4CF452B09F075CE89E090E0C5
:100B5000E6E1F1E0A2CF82E190E0E6E2F1E09DCFB4
:100B600080919001882309F472CF853009F46FCF0A
:100B70008091E80083FD6BCF8091E80082FDA1CFDA
:100B80008091E80080FF97CF8091F20090E02115DE
:100B9000310519F08830910550F041E0089709F0CF
:100BA00040E08091E8008E778093E80084CF449104
:100BB0004093F1003196215031090196E8CF8038F9
:100BC00009F039CE8091E800877F8093E80080911A
:100BD00091018093F10023CE81112DCE00919401DB
:100BE000023008F028CE8091E800877F8093E800EB
:100BF000009391010E94B401002349F084E08093A6
:100C0000900146E261EC83E00E94D30114CE809112
:100C1000E30087FDF3CF81E0F2CF1F920F920FB672
:100C20000F9211242F933F934F935F936F937F9372
:100C30008F939F93AF93BF93EF93FF938091E100C6
:100C400082FF09C08091E20082FF05C08091E1002F
:100C50008B7F8093E1008091E10080FF17C080913D
:100C6000E20080FF13C08091E2008E7F8093E2005B
:100C70008091E20080618093E2008091D8008062E0
:100C80008093D80019BC85E0809390018091E100A9
:100C900084FF27C08091E20084FF23C084E089BDE7
:100CA00086E089BD09B400FEFDCF8091D8008F7D1C
:100CB0008093D8008091E1008F7E8093E100809145
:100CC000E2008F7E8093E2008091E2008160809359
:100CD000E20080919101882309F43FC084E0809371
:100CE00090018091E10083FF27C08091E20083FFA3
:100CF00023C08091E100877F8093E10082E08093B0
:100D00009001109291018091E1008E7F8093E1002B
:100D10008091E2008E7F8093E2008091E20080610A
:100D20008093E20042E060E080E00E94D301809185
:100D3000F00088608093F000FF91EF91BF91AF9138
:100D40009F918F917F916F915F914F913F912F91E3
:100D50000F900FBE0F901F9018958091E30087FDB4
:100D600002C081E0BCCF83E0BACF84B7877F84BF65
:100D70000FB6F894A8958091600088618093600018
:100D8000109260000FBE80E890E00FB6F894809358
:100D90006100909361000FBE8DE192E09093070196
:100DA0008093060189EC90E00E9406011092E20017
:100DB0001092E1008091E00081608093E0008091DA
:100DC000D8008F778093D80019BC80916300816030
:100DD0008093630010928901809163008E7F8093DD
:100DE000630081E0809389011092E2001092E1009B
:100DF0008091D8008F778093D8008091D800806848
:100E00008093D8008091D8008F7D8093D80084E0B3
:100E100089BD86E089BD09B400FEFDCF1092900126
:100E20001092910110928F0110928E0142E060E0C9
:100E300080E00E94D3018091E1008E7F8093E100E9
:100E40008091E20081608093E2008091E2008860FE
:100E50008093E2008091E0008E7F8093E0007894A0
:100E600082E084BD93E095BD9AEF97BD80936E00BC
:100E7000809190018430E1F70E9405028823C1F33C
:100E800087EB90E00E9406010E94060385EA90E04D
:100E90009F938F930E949F0185E990E09F938F938A
:100EA0000E949F010F900F900F900F90D0E0C0E034
:100EB0000EE810E0CE018F709927892B51F4DF9353
:100EC000CF931F930F930E949F010F900F900F904D
:100ED0000F906FEFCE010E9451082196C11584E05A
:100EE000D80741F78CE890E09F938F930E949F0171
:100EF00083EA90E09F938F930E949F010E940603D4
:100F000089EA90E00E9406010F900F900F900F90D9
:100F100083E0D82E08EE13E0C7EAD0E098E1E92E8E
:100F2000F12C20E4C22E80919001853009F44CC050
:100F30000E94A8015C0180918A0190918B01A81602
:100F4000B90661F0C501B8010E945F08892B31F430
:100F5000DF93CF930E949F010F900F90B0928B016F
:100F6000A0928A012091E4003091E50080918C01EB
:100F700090918D0128173907B1F28091E40090918A
:100F8000E50090938D0180938C010E9405028823D7
:100F900051F280919001843031F68091E9008F7098
:100FA0009091EC0090FD37C090E0892BD092E90041
:100FB0009091EB0090FF04C09091EE0097FD49C026
:100FC0008F708093E900AFCF80919001843009F455
:100FD000AACF10929A010FB6F894A895E0926000FB
:100FE0000FBEC092600083B7817F846083BF83B7E8
:100FF000816083BF7894889583B78E7F83BF0FB657
:10100000F894A895809160008861809360001092A8
:1010100060000FBE88CF90E8C8CFE0910101F09149
:101020000201E90FF11D20819F5F3091050193239B
:10103000909304012093F1009091E80095FD09C080
:101040009091E80090FF05C09091E8009E77909302
:10105000E8009091040120910301291721F02091CB
:10106000E80025FDDACF9091F200992309F4A8CF8A
:101070009091E80090FFA4CF9091E80095FD06C004
:101080009091E8009E779093E8009ACF1092F1003B
:10109000F3CFF999FECF92BD81BDF89A992780B51B
:1010A0000895262FF999FECF1FBA92BD81BD20BDAC
:1010B0000FB6F894FA9AF99A0FBE01960895AA1BF2
:1010C000BB1B51E107C0AA1FBB1FA617B70710F033
:1010D000A61BB70B881F991F5A95A9F78095909565
:1010E000BC01CD010895EE0FFF1F0590F491E02D96
:0610F0000994F894FFCF03
:0610F60005080100007F67
:00000001FF

View file

@ -0,0 +1,290 @@
:100000000C94CC000C9414010C9414010C94140165
:100010000C9414010C9414010C9414010C9414010C
:100020000C9414010C9414010C94B5060C943B042C
:100030000C9412040C9414010C9414010C941401EB
:100040000C9414010C9414010C9414010C941401DC
:100050000C9414010C94EC030C9414010C941401F2
:100060000C9414010C9414010C9414010C941401BC
:100070000C9414010C9414010C9414010C941401AC
:100080000C9414010C9414010C9414010C9414019C
:100090000C9414010C9414010C9414010C9414018C
:1000A0000C9414010C9414010C9414010A002530D2
:1000B000325820000A253034583A200065657072A5
:1000C0006F6D3A000A00253034583A20006565709B
:1000D000726F6D20776970653A20000A000A002E61
:1000E000000A4C6F6F702073746172742E0A000ADC
:1000F00055534220636F6E666967757265642E0A98
:10010000000A544D4B3A3630343735642F4C55463F
:10011000413A6436613764660A000631FF0974A10A
:10012000010975150026FF009520750881020976E2
:10013000150026FF00952075089102C009022200D3
:10014000010100A0320904000001030000000921A0
:100150001101000122220007058303200001120182
:10016000100100000008EDFEEEEE010001020001AA
:10017000180345004500500052004F004D0020007C
:1001800054006F006F006C000000080354004D0025
:100190004B0000000403090411241FBECFEFDAE076
:1001A000DEBFCDBF04B603FE28C080911F02909130
:1001B0002002A0912102B09122028730904BA740EB
:1001C000B04BD9F410921F0210922002109221021B
:1001D0001092220214BE0FB6F894A8958091600088
:1001E000886180936000109260000FBE1092010839
:1001F00010920008E0E0F8E3099511E0A0E0B1E01A
:10020000E6EFF1E102C005900D92A630B107D9F7F3
:1002100022E0A6E0B1E001C01D92AF31B207E1F7E4
:100220000E9486070C94F9080C940000FF93EF934A
:10023000E0910601F0910701309709F00995EF91DF
:10024000FF910895FC018591803011F0EFDFFBCF25
:100250000895FF27E0E230E247FF0CC0419597FF89
:1002600009C0EDE26095709580959095611D711DB6
:10027000811D911D27FF02C0219530E350E2AA277E
:10028000660F771F881F991FAA1FA41710F0A41BC1
:1002900063955A95A9F7AA3008F0A95FA05DAF93BE
:1002A000F395611571058105910541F7ED3211F462
:1002B000EF93F395F21718F43F93F395FBCF8F91DB
:1002C000B5DFFA95E1F70895E991F99185918030CC
:1002D00021F0853219F0AADFF9CF089520E0E894E3
:1002E00055915532C1F3503311F4689455915A33F6
:1002F00048F4505390F3220F022E220F220F200DAC
:10030000250FF4CF0EF4219589919991533619F365
:10031000533729F1533559F1BC0188279927E894BF
:100320005C3621F48991999168945591543639F449
:1003300046EF7EF077FF0DC08FEF9FEF0AC0553775
:100340004AE039F0583540E121F0523642E009F0F8
:100350000895FF93EF937DDFEF91FF91B7CFFF9368
:10036000EF93FC0181918030B9F360DFFBCFFF9305
:10037000EF9368DFF1CFDF93CF93CDB7DEB725964C
:10038000A3DFCF91DF9108952FB7F89480911B02DE
:1003900090911C02A0911D02B0911E022FBF0895E2
:1003A000E8EDF0E080818E7F80831092E200109271
:1003B000DA001092E100A0EEB0E08C9181608C93A5
:1003C00080818F77808319BCA7EDB0E08C918E7F00
:1003D0008C9380818F7E808310920D02089580918E
:1003E000120287FF13C08091E80082FF06C080914F
:1003F000E8008B778093E80004C08091100281119F
:10040000F2CF0895809110028823D9F38091E800FB
:1004100080FFF8CF8091E8008E77ECCF982F9093F3
:10042000E900242F762F50E0891731F07091EC000D
:100430002091ED005091F00021FD07C09F5F9730A3
:1004400071F78093E90081E008953091EB003E7FE1
:100450003093EB003091ED003D7F3093ED00309113
:10046000EB0031603093EB007093EC002093ED00D3
:100470005093F0002091EE0027FDE0CF80E008953A
:10048000CF92DF92EF92FF920F931F93CF93DF9360
:10049000C8EDD0E088818F7E8883E7EDF0E0808131
:1004A0008160808384E082BF81E080930D02888137
:1004B0008E7F888302EE10E0F80110821092DA003D
:1004C00081EEC82ED12CF601108288818F77888327
:1004D00088818068888388818F7D888319BC109289
:1004E00010021092110210920F0210920E0290EE62
:1004F000E92EF12CF70180818B7F808388818160D8
:10050000888342E060E080E00E940E02F601808174
:100510008E7F8083F8018081816080838081886004
:100520008083F70180818E7F8083888180618883CA
:10053000DF91CF911F910F91FF90EF90DF90CF90BF
:10054000089580910802811113C09FB7F8944091DB
:100550001B0250911C0260911D0270911E029FBFF0
:10056000443C59406105710518F081E08093080210
:100570000895EF92FF920F931F93CF93DF93D82F9D
:100580000FB607FE46C080911002843079F080914A
:10059000030190E001962091050130E0822393232E
:1005A000209104012817190609F0CDC00E94A1026C
:1005B00081110FC08091030190E001962091050107
:1005C00030E082239323209104012817190609F0B3
:1005D000BAC00E94C4018C01C091E900CF70809123
:1005E000EC0080FD37C080E0C82B83E08093E900F9
:1005F00085E0E82E8091EB0085FD08C08091EB003E
:1006000080FF04C08091EE0087FD44C0CF70C0938E
:10061000E900E09103018E2F90E001962091050101
:1006200030E082239323209104012817190609F44E
:1006300082C08091010190910201E80FF92FF11D14
:10064000D083809103018F5F90910501892380936E
:10065000030171C080E8C8CFE0910101F09102016F
:10066000E80FF11D90818F5F209105018223809317
:1006700004019093F1008091E80085FD0BC080910A
:10068000E80080FF07C08091E8008E778093E80043
:10069000E09200018091040190910301981741F1CB
:1006A0009091E80095FDD8CF80E029C01092F1002C
:1006B00032C08091030190E001962091050130E065
:1006C00082239323209104012817190609F09ECF55
:1006D000F0900001FF2009F499CF0E94C401801717
:1006E000910709F487CFFA94F09200018C0182CF30
:1006F0008091E80085FFD8CFD093F10081E0209170
:10070000F3009091F200322F292F232B79F0909152
:10071000E80090FF0BC09091E80095FDC7CF909145
:10072000E8009E779093E800E0920001882309F2A8
:10073000CF70C093E90080E0DF91CF911F910F91BE
:10074000FF90EF900895E091030173CFEF92FF9235
:100750000F931F93CF93DF938CEB90E09F938F9336
:100760000E94BB010F900F90D0E0C0E084EBE82E18
:1007700080E0F82E0EEA10E0CE018F709927892BC9
:1007800051F4DF93CF93FF92EF920E94BB010F9041
:100790000F900F900F90CE010E94C9081F928F9367
:1007A0001F930F930E94BB0121960F900F900F9003
:1007B0000F90C11584E0D807F9F68CEA90E09F937A
:1007C0008F930E94BB010F900F90DF91CF911F91EB
:1007D0000F91FF90EF90089578941F920F920FB6AB
:1007E0000F9211248F939F93AF93BF9380911B021D
:1007F00090911C02A0911D02B0911E020196A11DB4
:10080000B11D80931B0290931C02A0931D02B09314
:100810001E02BF91AF919F918F910F900FBE0F90CD
:100820001F9018951F920F920FB60F9211248F935D
:100830009F93AF93BF9380911A02811113C080914F
:100840001B0290911C02A0911D02B0911E024196C4
:10085000A11DB11D80931B0290931C02A0931D0249
:10086000B0931E02BF91AF919F918F910F900FBED9
:100870000F901F9018951F920F920FB60F92112490
:100880000F931F932F933F934F935F936F937F9398
:100890008F939F93AF93BF93EF93FF93CF93DF9388
:1008A000CDB7DEB7AA97DEBFCDBF1091E9001F70AC
:1008B0008091EC0080FF2FC080E8182B1092E90097
:1008C0008091F000877F8093F0007894E2E1F2E07D
:1008D0008AE192E02091F10021938E179F07D1F7D2
:1008E0008091E80083FF47C080911202909113022B
:1008F0009A3008F040C0E92FF0E0EF57FB4F0C941E
:10090000F3088D04B304BB04B304BB042E055005E7
:10091000BB048706940680E0D0CF803889F0823807
:1009200051F5809116028F70873028F58093E90089
:100930008091EB0085FB882780F91092E90006C0C2
:1009400080910E0290910F02911182609091E800C7
:10095000977F9093E8008093F1001092F1008091CE
:10096000E8008E7749C0282F2D7F29F48823B1F124
:10097000823009F446C08091E80083FF0AC080916C
:10098000E800877F8093E8008091EB00806280938D
:10099000EB001092E9008091F00088608093F000F5
:1009A0001F701093E900AA960FB6F894DEBF0FBE31
:1009B000CDBFDF91CF91FF91EF91BF91AF919F910B
:1009C0008F917F916F915F914F913F912F911F91E7
:1009D0000F910F900FBE0F901F90189580911402E9
:1009E000813049F6933009F080E080930F02109235
:1009F000E9008091E800877F8093E8000E94EF0182
:100A0000BACF809114028111F2CF809116028F70BB
:100A10002FEF280F263008F0AECF8093E900209109
:100A2000EB0020FFE4CF933031F48091EB00806243
:100A30008093EB00DCCF9091EB0090619093EB0002
:100A400021E030E001C0220F8A95EAF72093EA0006
:100A50001092EA008091EB008860EACF81118BCF81
:100A6000009114020F778091E3008078802B8093AF
:100A7000E3008091E800877F8093E8000E94EF0107
:100A80008091E80080FFFCCF8091E3008068809334
:100A9000E30083E0011101C082E0809310026BCF7C
:100AA0008058823008F067CF2091140230911502EF
:100AB0002C3D83E0380709F07EC083E08A838AE218
:100AC00089834FB7F894DE01139620E03EE051E2AF
:100AD000E32FF0E050935700E49120FF03C0E2952C
:100AE000EF703F5FEF708E2F90E0EA30C0F0C79656
:100AF0008D939D932F5F243159F74FBF8091E8006C
:100B0000877F8093E80080911802909119028A32C1
:100B1000910508F04DC040E0FE0131962AC0C09614
:100B2000E7CF209110022223B1F12530A1F12091CD
:100B3000E80023FD30C02091E80022FD1EC0209176
:100B4000E80020FF16C02091F3003091F200232727
:100B500032272327009719F02830310510F141E0A2
:100B60002830310509F040E02091E8002E772093ED
:100B7000E8000097B1F64111D4CF8091E80082FDE2
:100B80000AC080911002882331F0853021F08091D5
:100B9000E80083FFF2CF8091E8008B778093E80034
:100BA000EACE41914093F10001972F5F3F4FD2CFA2
:100BB0008AE290E0B0CF4091160250911702832F45
:100BC00099278330910509F43EC080F58130910565
:100BD00009F465C0029709F0CECE82E290E0ECE322
:100BE000F1E02091E800277F2093E800209118028F
:100BF000309119028217930708F49C0140E02115F7
:100C0000310509F051C041114FC08091E80082FDCB
:100C1000C2CF80911002882309F4BDCF853009F43A
:100C2000BACF8091E80083FFF0CFB5CF8132910534
:100C300071F18232910509F09ECE452B09F09BCED1
:100C4000EAE1F1E0CECF332721303105C1F060F089
:100C50002230310509F08FCEE0E7F1E0E4918E2FEC
:100C600090E0E0E7F1E007C0E4E9F1E0E4918E2FE5
:100C700090E0E4E9F1E0009709F47DCEB2CFEAE834
:100C8000F1E0E4918E2F90E0EAE8F1E0F4CF452B1B
:100C900009F071CE89E090E0EEE4F1E0A2CF82E1CC
:100CA00090E0EEE5F1E09DCF80911002882309F4F9
:100CB00072CF853009F46FCF8091E80083FD6BCF50
:100CC0008091E80082FDA1CF8091E80080FF97CF5E
:100CD0008091F3009091F2008927982789272115A8
:100CE000310519F08830910550F041E0089709F07E
:100CF00040E08091E8008E778093E80080CF4491B7
:100D00004093F1003196215031090196E8CF8038A7
:100D100009F031CE8091E800877F8093E8008091D0
:100D200011028093F1001BCE811125CE0091140297
:100D3000023008F020CE8091E800877F8093E800A1
:100D4000009311020E94EF01002349F084E0809398
:100D5000100246E261EC83E00E940E020CCE80910C
:100D6000E30087FDF3CF81E0F2CF1F920F920FB621
:100D70000F9211242F933F934F935F936F937F9321
:100D80008F939F93AF93BF93EF93FF938091E10075
:100D900082FF09C08091E20082FF05C08091E100DE
:100DA0008B7F8093E1008091DA0080FF1FC08091EB
:100DB000D80080FF1BC08091DA008E7F8093DA001C
:100DC0008091D90080FF94C080E189BD82E189BD16
:100DD00009B400FEFDCF81E08093100280910D02E6
:100DE000811104C00E94D0010E9440028091E10064
:100DF00080FF17C08091E20080FF13C08091E20065
:100E00008E7F8093E2008091E20080618093E20017
:100E10008091D80080628093D80019BC85E08093CF
:100E200010028091E10084FF27C08091E20084FFDE
:100E300023C080E189BD82E189BD09B400FEFDCFF8
:100E40008091D8008F7D8093D8008091E1008F7EC3
:100E50008093E1008091E2008F7E8093E200809198
:100E6000E20081608093E20080911102882309F4FE
:100E700045C084E0809310028091E10083FF27C089
:100E80008091E20083FF23C08091E100877F8093FF
:100E9000E10082E080931002109211028091E10043
:100EA0008E7F8093E1008091E2008E7F8093E2004C
:100EB0008091E20080618093E20042E060E080E0A7
:100EC0000E940E028091F00088608093F000FF91F4
:100ED000EF91BF91AF919F918F917F916F915F91B2
:100EE0004F913F912F910F900FBE0F901F9018952B
:100EF00019BC1092100210920D0278CF8091E3007D
:100F000087FD02C081E0B6CF83E0B4CF84B7877F8E
:100F100084BF0FB6F894A895809160008861809393
:100F20006000109260000FBE80E890E00FB6F89469
:100F300080936100909361000FBE89EB92E09093E3
:100F400007018093060181E091E00E9422010E9446
:100F5000D0010E944002789482E084BD93E095BD68
:100F60009AEF97BD80936E00809110028430E1F774
:100F70000E94A1028823C1F38FEE90E00E9422011B
:100F80000E94A6038DED90E09F938F930E94BB017A
:100F90008DEC90E09F938F930E94BB010F900F9078
:100FA0000F900F90D0E0C0E006EC10E0CE018F7003
:100FB0009927892B51F4DF93CF931F930F930E94AE
:100FC000BB010F900F900F900F906FEFCE010E941A
:100FD000D1082196C11584E0D80741F784EC90E050
:100FE0009F938F930E94BB018BED90E09F938F9313
:100FF0000E94BB010E94A60381EE90E00E942201A4
:101000000F900F900F900F9083E0D82E08EE13E012
:10101000CFEDD0E098E1E92EF12C20E4C22E8091B2
:101020001002853009F44CC00E94C4015C0180911B
:10103000090290910A02A816B90661F0C501B8012B
:101040000E94DF08892B31F4DF93CF930E94BB010C
:101050000F900F90B0920A02A09209022091E40032
:101060003091E50080910B0290910C02281739070E
:10107000B1F28091E4009091E50090930C0280938E
:101080000B020E94A102882351F280911002843049
:1010900031F68091E9008F709091EC0090FD37C09F
:1010A00090E0892BD092E9009091EB0090FF04C072
:1010B0009091EE0097FD49C08F708093E900AFCF0B
:1010C00080911002843009F4AACF10921A020FB650
:1010D000F894A895E09260000FBEC092600083B7BC
:1010E000817F846083BF83B7816083BF7894889554
:1010F00083B78E7F83BF0FB6F894A8958091600068
:10110000886180936000109260000FBE88CF90E8E5
:10111000C8CFE0910101F0910201E90FF11D20819A
:101120009F5F309105019323909304012093F10078
:101130009091E80095FD09C09091E80090FF05C0EE
:101140009091E8009E779093E8009091040120919F
:101150000301291721F02091E80025FDDACF209125
:10116000F3009091F200322F292F232B09F4A4CF02
:101170009091E80090FFA0CF9091E80095FD06C007
:101180009091E8009E779093E80096CF1092F1003E
:10119000F3CFF999FECF92BD81BDF89A992780B51A
:1011A0000895262FF999FECF1FBA92BD81BD20BDAB
:1011B0000FB6F894FA9AF99A0FBE01960895AA1BF1
:1011C000BB1B51E107C0AA1FBB1FA617B70710F032
:1011D000A61BB70B881F991F5A95A9F78095909564
:1011E000BC01CD010895EE0FFF1F0590F491E02D95
:0611F0000994F894FFCF02
:0611F6000508010000FFE6
:00000001FF