From 63b280f4fd14da2e40127e1145d2cfa3dd3d6d52 Mon Sep 17 00:00:00 2001 From: b Date: Thu, 28 Jul 2022 23:37:37 +0200 Subject: [PATCH 1/1] initial state as of 28.7.2022 --- Makefile | 645 +++++ avt2994-avrdude.txt | 149 + code_page_template.py | 32 + cp.txt | 16 + esc.txt | 106 + keyboard-patterns.c | 3748 +++++++++++++++++++++++++ keyboard-patterns.h | 380 +++ keyboard-patterns.py | 254 ++ keyboard-patterns.txt | 1979 ++++++++++++++ keyboard.h | 355 +++ license.txt | 5 + maszyna.c | 6072 +++++++++++++++++++++++++++++++++++++++++ maszyna_.c | 5228 +++++++++++++++++++++++++++++++++++ uni.py | 17 + uni.txt | 27 + update-template.py | 110 + 16 files changed, 19123 insertions(+) create mode 100644 Makefile create mode 100644 avt2994-avrdude.txt create mode 100644 code_page_template.py create mode 100644 cp.txt create mode 100644 esc.txt create mode 100644 keyboard-patterns.c create mode 100644 keyboard-patterns.h create mode 100755 keyboard-patterns.py create mode 100644 keyboard-patterns.txt create mode 100644 keyboard.h create mode 100644 license.txt create mode 100644 maszyna.c create mode 100644 maszyna_.c create mode 100755 uni.py create mode 100644 uni.txt create mode 100755 update-template.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a10c3c0 --- /dev/null +++ b/Makefile @@ -0,0 +1,645 @@ +# Hey Emacs, this is a -*- makefile -*- +#---------------------------------------------------------------------------- +# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al. +# +# Released to the Public Domain +# +# Additional material for this makefile was written by: +# Peter Fleury +# Tim Henigan +# Colin O'Flynn +# Reiner Patommel +# Markus Pfaff +# Sander Pool +# Frederik Rouleau +# Carlos Lamas +# +# I (Balthasar Szczepański) made some changes for this project, +# to allow programming with the avt2994 tool and program fuse byte as well. +# +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device, using avrdude. +# Please customize the avrdude settings below first! +# +# make program-fuse = as above but will program the fuse bytes too. +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + + +# MCU name +# MCU = atmega328p +MCU = atmega1284 + + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# Typical values are: +# F_CPU = 1000000 +# F_CPU = 1843200 +# F_CPU = 2000000 +# F_CPU = 3686400 +# F_CPU = 4000000 +# F_CPU = 7372800 +# F_CPU = 8000000 +# F_CPU = 11059200 +# F_CPU = 14745600 +# F_CPU = 16000000 +# F_CPU = 18432000 +# F_CPU = 20000000 +F_CPU = 8000000 + + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + + +# Target file name (without extension). +TARGET = maszyna + + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = . + + +# List C source files here. (C dependencies are automatically generated.) +SRC = $(TARGET).c keyboard-patterns.c + + +# List C++ source files here. (C dependencies are automatically generated.) +CPPSRC = + + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +#ASRC = pwm.S +ASRC = + + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +OPT = s + + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +# DEBUG = dwarf-2 +DEBUG = + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRAINCDIRS = + + +# Compiler flag to set the C Standard level. +# c89 = "ANSI" C +# gnu89 = c89 plus GCC extensions +# c99 = ISO C99 standard (not yet fully implemented) +# gnu99 = c99 plus GCC extensions +CSTANDARD = -std=gnu99 + + +# Place -D or -U options here for C sources +CDEFS = -DF_CPU=$(F_CPU)UL + + +# Place -D or -U options here for ASM sources +ADEFS = -DF_CPU=$(F_CPU) + +# Place -D or -U options here for C++ sources +CPPDEFS = -DF_CPU=$(F_CPU)UL +#CPPDEFS += -D__STDC_LIMIT_MACROS +#CPPDEFS += -D__STDC_CONSTANT_MACROS + + + +#---------------- Compiler Options C ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +# CFLAGS = -g$(DEBUG) +CFLAGS = +CFLAGS += $(CDEFS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char +CFLAGS += -funsigned-bitfields +CFLAGS += -fpack-struct +CFLAGS += -fshort-enums +CFLAGS += -Wall +CFLAGS += -Wstrict-prototypes +#CFLAGS += -mshort-calls +#CFLAGS += -fno-unit-at-a-time +#CFLAGS += -Wundef +#CFLAGS += -Wunreachable-code +#CFLAGS += -Wsign-compare +CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) + + +#---------------- Compiler Options C++ ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +# CPPFLAGS = -g$(DEBUG) +CPPFLAGS = +CPPFLAGS += $(CPPDEFS) +CPPFLAGS += -O$(OPT) +CPPFLAGS += -funsigned-char +CPPFLAGS += -funsigned-bitfields +CPPFLAGS += -fpack-struct +CPPFLAGS += -fshort-enums +CPPFLAGS += -fno-exceptions +CPPFLAGS += -Wall +CPPFLAGS += -Wundef +#CPPFLAGS += -mshort-calls +#CPPFLAGS += -fno-unit-at-a-time +#CPPFLAGS += -Wstrict-prototypes +#CPPFLAGS += -Wunreachable-code +#CPPFLAGS += -Wsign-compare +CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) +CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +#CPPFLAGS += $(CSTANDARD) + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +# -listing-cont-lines: Sets the maximum number of continuation lines of hex +# dump that will be displayed for a given single line of source input. +ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 + + +#---------------- Library Options ---------------- +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +# If this is left blank, then it will use the Standard printf version. +PRINTF_LIB = +#PRINTF_LIB = $(PRINTF_LIB_MIN) +#PRINTF_LIB = $(PRINTF_LIB_FLOAT) + + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +# If this is left blank, then it will use the Standard scanf version. +SCANF_LIB = +#SCANF_LIB = $(SCANF_LIB_MIN) +#SCANF_LIB = $(SCANF_LIB_FLOAT) + + +MATH_LIB = -lm + + +# List any extra directories to look for libraries here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRALIBDIRS = + + + +#---------------- External Memory Options ---------------- + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + + + +#---------------- Linker Options ---------------- +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +#LDFLAGS += -T linker_script.x + + + +#---------------- Programming Options (avrdude) ---------------- + +# Programming hardware +# Type: avrdude -c ? +# to get a full listing. +# +# see avt1994-avrdude.txt +AVRDUDE_PROGRAMMER = avt2994 + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = usb:AR0K62QF + +AVRDUDE_BAUD = 57600 +# AVRDUDE_BITCLOCK = 400 +AVRDUDE_BITCLOCK = 400 +#AVRDUDE_BAUD = 115200 +#old bootl.=57600, new=115200 + + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).elf +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep +AVRDUDE_WRITE_FUSE = -U lfuse:w:$(TARGET).elf -U hfuse:w:$(TARGET).elf -U efuse:w:$(TARGET).elf + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -B $(AVRDUDE_BITCLOCK) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# Define programs and commands. +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +REMOVEDIR = rm -rf +COPY = cp +WINSHELL = cmd +PY = python3 + + +# Define Messages +# English +MSG_ERRORS_NONE = Errors: none +MSG_BEGIN = -------- begin -------- +MSG_END = -------- end -------- +MSG_SIZE_BEFORE = Size before: +MSG_SIZE_AFTER = Size after: +MSG_COFF = Converting to AVR COFF: +MSG_EXTENDED_COFF = Converting to AVR Extended COFF: +MSG_FLASH = Creating load file for Flash: +MSG_EEPROM = Creating load file for EEPROM: +MSG_EXTENDED_LISTING = Creating Extended Listing: +MSG_SYMBOL_TABLE = Creating Symbol Table: +MSG_LINKING = Linking: +MSG_COMPILING = Compiling C: +MSG_COMPILING_CPP = Compiling C++: +MSG_ASSEMBLING = Assembling: +MSG_CLEANING = Cleaning project: +MSG_CREATING_LIBRARY = Creating library: + + + + +# Define all object files. +OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o) + +# Define all listing files. +LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + + + + +# Default target. +all: begin gccversion sizebefore build sizeafter end + +# Change the build target to build a HEX file or a library. +build: elf hex eep lss sym +#build: lib + + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym +LIBNAME=lib$(TARGET).a +lib: $(LIBNAME) + +keyboard-patterns.h: keyboard-patterns.c + +keyboard-patterns.c: keyboard-patterns.txt keyboard-patterns.py + $(PY) keyboard-patterns.py keyboard-patterns.txt keyboard-patterns.h keyboard-patterns.c + + +# Eye candy. +# AVR Studio 3.x does not check make's exit code but relies on +# the following magic strings to be generated by the compile job. +begin: + @echo + @echo $(MSG_BEGIN) + +end: + @echo $(MSG_END) + @echo + + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf + +sizebefore: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ + 2>/dev/null; echo; fi + +sizeafter: + @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ + 2>/dev/null; echo; fi + + + +# Display compiler version information. +gccversion : + @$(CC) --version + + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep $(TARGET).elf + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +program-fuse: $(TARGET).hex $(TARGET).eep $(TARGET).elf + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_FUSE) $(AVRDUDE_WRITE_EEPROM) + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(TARGET).elf + @echo + @echo $(MSG_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + @echo + @echo $(MSG_EXTENDED_COFF) $(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + + +# Create final output files (.hex, .eep) from ELF output file. +%.hex: %.elf + @echo + @echo $(MSG_FLASH) $@ + $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@ + +%.eep: %.elf + @echo + @echo $(MSG_EEPROM) $@ + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 + +# Create extended listing file from ELF output file. +%.lss: %.elf + @echo + @echo $(MSG_EXTENDED_LISTING) $@ + $(OBJDUMP) -h -S -z $< > $@ + +# Create a symbol table from ELF output file. +%.sym: %.elf + @echo + @echo $(MSG_SYMBOL_TABLE) $@ + $(NM) -n $< > $@ + + + +# Create library from object files. +.SECONDARY : $(TARGET).a +.PRECIOUS : $(OBJ) +%.a: $(OBJ) + @echo + @echo $(MSG_CREATING_LIBRARY) $@ + $(AR) $@ $(OBJ) + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +%.elf: $(OBJ) + @echo + @echo $(MSG_LINKING) $@ + $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c keyboard-patterns.h + @echo + @echo $(MSG_COMPILING) $< + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create object files from C++ source files. +$(OBJDIR)/%.o : %.cpp keyboard-patterns.h + @echo + @echo $(MSG_COMPILING_CPP) $< + $(CC) -c $(ALL_CPPFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +%.s : %.c keyboard-patterns.h + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C++ source files. +%.s : %.cpp keyboard-patterns.h + $(CC) -S $(ALL_CPPFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +$(OBJDIR)/%.o : %.S keyboard-patterns.h + @echo + @echo $(MSG_ASSEMBLING) $< + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + +# Create preprocessed source for use in sending a bug report. +%.i : %.c keyboard-patterns.h + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ + + +# Target: clean project. +clean: begin clean_list end + +clean_list : + @echo + @echo $(MSG_CLEANING) + $(REMOVE) $(TARGET).hex + $(REMOVE) $(TARGET).eep + $(REMOVE) $(TARGET).cof + $(REMOVE) $(TARGET).elf + $(REMOVE) $(TARGET).map + $(REMOVE) $(TARGET).sym + $(REMOVE) $(TARGET).lss + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) + $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) + $(REMOVE) $(SRC:.c=.s) + $(REMOVE) $(SRC:.c=.d) + $(REMOVE) $(SRC:.c=.i) + $(REMOVEDIR) .dep + + +# Create object files directory +$(shell mkdir $(OBJDIR) 2>/dev/null) + + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program debug gdb-config + + diff --git a/avt2994-avrdude.txt b/avt2994-avrdude.txt new file mode 100644 index 0000000..9070f19 --- /dev/null +++ b/avt2994-avrdude.txt @@ -0,0 +1,149 @@ +Install avrdude gcc-avr avr-libc + +Programator AVT2994 +FTDI232RL. + +MAP: + +232RL AVR + RxD MOSI + TxD MISO + DTR RST + RTS SCK + + FT232RL: + +------+ + TxD D0 |1* 28| OSCO + DTR D4 |2 27| OSCI + RTS D2 |3 26| TEST +VccIO |4 25| AGND + RxD D1 |5 24| NC + DI D7 |6 23| C0 CBUS0 + GND |7 22| C1 CBUS1 + NC |8 21| GND + DSR D5 |9 20| Vcc + DCD D6 |10 19| RESET + CTS D3 |11 18| GND +CBUS4 |12 17| 3V3OUT +CBUS2 C2 |13 16| USBDM +CBUS3 C3 |14 15| USBDP + +------+ + + +/etc/avrdude.conf + +programmer + id = "avt2994"; + desc = "UniProgUSB AVT kit 2994"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 0; # TxD + sck = 2; # RTS + mosi = 1; # RxD + reset = 4; # DTR +; + + + 328P + +--\/--+ +[DTR] RST C6 |1* 28| C5 + RX D0 |2 27| C4 + TX D1 |3 26| C3 + D2 |4 25| C2 + D3 |5 24| C1 + D4 |6 23| C0 + [+] VCC |7 22| GND [-] + [-] GND |8 21| AREF + X1 B6 |9 20| AVCC [+] + X2 B7 |10 19| B5 SCK [RTS] + D5 |11 18| B4 MISO [TX] + D6 |12 17| B3 MOSI [RX] + D7 |13 16| B2 + B0 |14 15| B1 + +------+ + +> sudo dmesg | tail +[sudo] password for b: +[18049.452272] usb 4-2: USB disconnect, device number 7 +[18051.272131] usb 4-2: new full-speed USB device number 8 using uhci_hcd +[18051.486223] usb 4-2: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00 +[18051.486227] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[18051.486229] usb 4-2: Product: FT232R USB UART +[18051.486230] usb 4-2: Manufacturer: FTDI +[18051.486232] usb 4-2: SerialNumber: AR0K62QF +[18051.493294] ftdi_sio 4-2:1.0: FTDI USB Serial Device converter detected +[18051.493330] usb 4-2: Detected FT232RL +[18051.495373] usb 4-2: FTDI USB Serial Device converter now attached to ttyUSB0 + +> avrdude -v -c avt2994 -p m328p -P usb:AR0K62QF -B 400 + +avrdude: Version 6.3-20171130 + Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ + Copyright (c) 2007-2014 Joerg Wunsch + + System wide configuration file is "/etc/avrdude.conf" + User configuration file is "/home/b/.avrduderc" + User configuration file does not exist or is not a regular file, skipping + + Using Port : usb:AR0K62QF + Using Programmer : avt2994 + Setting bit clk period : 400.0 + AVR Part : ATmega328P + Chip Erase delay : 9000 us + PAGEL : PD7 + BS2 : PC2 + RESET disposition : dedicated + RETRY pulse : SCK + serial program mode : yes + parallel program mode : yes + Timeout : 200 + StabDelay : 100 + CmdexeDelay : 25 + SyncLoops : 32 + ByteDelay : 0 + PollIndex : 3 + PollValue : 0x53 + Memory Detail : + + Block Poll Page Polled + Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack + ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- + eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff + flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff + lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 + hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 + efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 + lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 + calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00 + signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00 + + Programmer Type : ftdi_syncbb + Description : UniProgUSB AVT kit 2994 + Pin assignment : 0..7 = DBUS0..7 + VCC = (not used) + BUFF = (not used) + RESET = 4 + SCK = 2 + MOSI = 1 + MISO = 0 + ERR LED = (not used) + RDY LED = (not used) + PGM LED = (not used) + VFY LED = (not used) + +avrdude: AVR device initialized and ready to accept instructions + +Reading | ################################################## | 100% 0.10s + +avrdude: Device signature = 0x1e950f (probably m328p) +avrdude: safemode: lfuse reads as 62 +avrdude: safemode: hfuse reads as D9 +avrdude: safemode: efuse reads as FF + +avrdude: safemode: lfuse reads as 62 +avrdude: safemode: hfuse reads as D9 +avrdude: safemode: efuse reads as FF +avrdude: safemode: Fuses OK (E:FF, H:D9, L:62) + +avrdude done. Thank you. + diff --git a/code_page_template.py b/code_page_template.py new file mode 100644 index 0000000..1bd5a1c --- /dev/null +++ b/code_page_template.py @@ -0,0 +1,32 @@ +encodings = [ + 'ascii', + 'cp852', + 'cp1250', + 'iso8859-2' +] + +B = [bytes([i]) for i in range (0, 0x100)] +all_chars = [] + +for enc in encodings: + print (enc + ':') + + offset = 0 if enc == 'ascii' else 0x80 + + for i in range (offset, offset+0x80, 0x10): + l = '' + for j in range (0, 0x10): + t = B[i+j].decode(enc, errors='ignore') + if t == '': + t = '_' + c = ord(t) + l += ' %04x' % c + + if not (c in all_chars): + all_chars.append(c) + print (l) + +d = sorted(all_chars) + +for c in d: + print((' %04x: ' % c) + chr(c)) \ No newline at end of file diff --git a/cp.txt b/cp.txt new file mode 100644 index 0000000..8a2ec8a --- /dev/null +++ b/cp.txt @@ -0,0 +1,16 @@ + |0 1 2 3 4 5 6 7 8 9 A B C D E F +-+-------------------------------- +2| ! " # $ % & ' ( ) * + , - . / +3|0 1 2 3 4 5 6 7 8 9 : ; < = > ? +4|@ A B C D E F G H I J K L M N O +5|P Q R S T U V W X Y Z [ \ ] ^ _ +6|` a b c d e f g h i j k l m n o +7|p q r s t u v w x y z { | } ~  +8|€  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž  +9| ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ +A|  ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ +B|° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ +C|À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï +D|Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß +E|à á â ã ä å æ ç è é ê ë ì í î ï +F|ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ diff --git a/esc.txt b/esc.txt new file mode 100644 index 0000000..fd436de --- /dev/null +++ b/esc.txt @@ -0,0 +1,106 @@ +ESC ( C 7 +ESC ( c 9 +ESC C 3 +ESC C NUL 4 +ESC N 3 +ESC O 2 +ESC Q 3 +ESC 1 3 +CR 1 +LF 1 +FF 1 +ESC $ 4 +ESC \ 4 +ESC ( V 7 +ESC ( v 7 +ESC J 3 +HT 1 +VT 1 +ESC f 4 +BS 1 +ESC ( U 6 +ESC 0 2 +ESC 2 2 +ESC 3 3 +ESC + 3 +ESC A 3 +ESC 1 2 +ESC D TERM NUL 35 +ESC B TERM NUL 19 +ESC b TERM NUL 19 +ESC / 3 +ESC e 4 +ESC a 3 +ESC ( t 8 +ESC t 3 +ESC R 3 +ESC & NUL ??? +ESC : NUL 5 +ESC % 3 +ESC x 3 +ESC k 3 +ESC X 5 +ESC c 4 +ESC P 2 +ESC M 2 +ESC g 2 +ESC p 3 +ESC SP 3 +ESC E 2 +ESC F 2 +ESC 4 2 +ESC 5 2 +ESC ! 3 +ESC G 2 +ESC H 2 +ESC - 3 +ESC ( - 8 +ESC S 3 +ESC T 2 +ESC q 3 +SI 1 +ESC SI 2 +DC2 1 +DO 1 +ESC SO 2 +DC4 1 +ESC W 3 +ESC w 3 +ESC ( ^ ??? +ESC 6 2 +ESC 7 2 +ESC I 3 +ESC m 3 +ESC EM 3 +ESC U 3 +ESC < 2 +BEL 1 +ESC 8 2 +ESC 9 2 +ESC s 3 +ESC ( G 6 +ESC ( i 6 +ESC . ??? +ESC . /2 8 +ESC * ??? +ESC ? 4 +ESC K ??? +ESC L ??? +ESC Y ??? +ESC Z ??? +ESC ^ ??? +ESC r 3 +ESC ( ??? +ESC @ 2 +CAN 1 +DEL 1 +DC1 1 +DC3 1 +ESC # 2 +ESC = 2 +ESC > 2 +ESC j 3 +ESC i 3 + + + diff --git a/keyboard-patterns.c b/keyboard-patterns.c new file mode 100644 index 0000000..596874e --- /dev/null +++ b/keyboard-patterns.c @@ -0,0 +1,3748 @@ +/* file autogenerated from keyboard-patterns.txt. do not edit - will be overwritten */ +#include +#include "keyboard.h" +#include "keyboard-patterns.h" + +const uint8_t ENC_C1[0x0B] = { + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, +}; + +uint8_t const * const * const CH_LIST[0x0B] = { + CH_ISO8859_1, + CH_ISO8859_2, + CH_ISO8859_3, + CH_ISO8859_4, + CH_ISO8859_9, + CH_ISO8859_10, + CH_ISO8859_13, + CH_ISO8859_15, + CH_ISO8859_16, + CH_CP1250, + CH_CP852, +}; + +uint8_t const * const KEYMAP_LIST[0x0B] = { + KEYMAP_ISO8859_1, + KEYMAP_ISO8859_2, + KEYMAP_ISO8859_3, + KEYMAP_ISO8859_4, + KEYMAP_ISO8859_9, + KEYMAP_ISO8859_10, + KEYMAP_ISO8859_13, + KEYMAP_ISO8859_15, + KEYMAP_ISO8859_16, + KEYMAP_CP1250, + KEYMAP_CP852, +}; + +uint8_t const * const CH_TABLE[0x0600] = { +/* ASCII 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 00 */ CH_0000, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 10 */ CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 20 */ CH_0020, CH_0021, CH_0022, CH_0023, CH_0024, CH_0025, CH_0026, CH_0027, CH_0028, CH_0029, CH_002A, CH_002B, CH_002C, CH_002D, CH_002E, CH_002F, +/* 30 */ CH_0030, CH_0031, CH_0032, CH_0033, CH_0034, CH_0035, CH_0036, CH_0037, CH_0038, CH_0039, CH_003A, CH_003B, CH_003C, CH_003D, CH_003E, CH_003F, +/* 40 */ CH_0040, CH_0041, CH_0042, CH_0043, CH_0044, CH_0045, CH_0046, CH_0047, CH_0048, CH_0049, CH_004A, CH_004B, CH_004C, CH_004D, CH_004E, CH_004F, +/* 50 */ CH_0050, CH_0051, CH_0052, CH_0053, CH_0054, CH_0055, CH_0056, CH_0057, CH_0058, CH_0059, CH_005A, CH_005B, CH_005C, CH_005D, CH_005E, CH_005F, +/* 60 */ CH_0060, CH_0061, CH_0062, CH_0063, CH_0064, CH_0065, CH_0066, CH_0067, CH_0068, CH_0069, CH_006A, CH_006B, CH_006C, CH_006D, CH_006E, CH_006F, +/* 70 */ CH_0070, CH_0071, CH_0072, CH_0073, CH_0074, CH_0075, CH_0076, CH_0077, CH_0078, CH_0079, CH_007A, CH_007B, CH_007C, CH_007D, CH_007E, CH_UNKN, +/* ISO8859_1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_00A1, CH_00A2, CH_00A3, CH_00A4, CH_00A5, CH_00A6, CH_00A7, CH_00A8, CH_00A9, CH_00AA, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_00AF, +/* B0 */ CH_00B0, CH_00B1, CH_00B2, CH_00B3, CH_00B4, CH_00B5, CH_00B6, CH_00B7, CH_00B8, CH_00B9, CH_00BA, CH_00BB, CH_00BC, CH_00BD, CH_00BE, CH_00BF, +/* C0 */ CH_00C0, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_00D0, CH_00D1, CH_00D2, CH_00D3, CH_00D4, CH_00D5, CH_00D6, CH_00D7, CH_00D8, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_00DD, CH_00DE, CH_00DF, +/* E0 */ CH_00E0, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_00F0, CH_00F1, CH_00F2, CH_00F3, CH_00F4, CH_00F5, CH_00F6, CH_00F7, CH_00F8, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_00FD, CH_00FE, CH_00FF, +/* ISO8859_2 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_0104, CH_02D8, CH_0141, CH_00A4, CH_013D, CH_015A, CH_00A7, CH_00A8, CH_0160, CH_015E, CH_0164, CH_0179, CH_00AD, CH_017D, CH_017B, +/* B0 */ CH_00B0, CH_0105, CH_02DB, CH_0142, CH_00B4, CH_013E, CH_015B, CH_02C7, CH_00B8, CH_0161, CH_015F, CH_0165, CH_017A, CH_02DD, CH_017E, CH_017C, +/* C0 */ CH_0154, CH_00C1, CH_00C2, CH_0102, CH_00C4, CH_0139, CH_0106, CH_00C7, CH_010C, CH_00C9, CH_0118, CH_00CB, CH_011A, CH_00CD, CH_00CE, CH_010E, +/* D0 */ CH_0110, CH_0143, CH_0147, CH_00D3, CH_00D4, CH_0150, CH_00D6, CH_00D7, CH_0158, CH_016E, CH_00DA, CH_0170, CH_00DC, CH_00DD, CH_0162, CH_00DF, +/* E0 */ CH_0155, CH_00E1, CH_00E2, CH_0103, CH_00E4, CH_013A, CH_0107, CH_00E7, CH_010D, CH_00E9, CH_0119, CH_00EB, CH_011B, CH_00ED, CH_00EE, CH_010F, +/* F0 */ CH_0111, CH_0144, CH_0148, CH_00F3, CH_00F4, CH_0151, CH_00F6, CH_00F7, CH_0159, CH_016F, CH_00FA, CH_0171, CH_00FC, CH_00FD, CH_0163, CH_02D9, +/* ISO8859_3 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_0126, CH_02D8, CH_00A3, CH_00A4, CH_UNKN, CH_0124, CH_00A7, CH_00A8, CH_0130, CH_015E, CH_011E, CH_0134, CH_00AD, CH_UNKN, CH_017B, +/* B0 */ CH_00B0, CH_0127, CH_00B2, CH_00B3, CH_00B4, CH_00B5, CH_0125, CH_00B7, CH_00B8, CH_0131, CH_015F, CH_011F, CH_0135, CH_00BD, CH_UNKN, CH_017C, +/* C0 */ CH_00C0, CH_00C1, CH_00C2, CH_UNKN, CH_00C4, CH_010A, CH_0108, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_UNKN, CH_00D1, CH_00D2, CH_00D3, CH_00D4, CH_0120, CH_00D6, CH_00D7, CH_011C, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_016C, CH_015C, CH_00DF, +/* E0 */ CH_00E0, CH_00E1, CH_00E2, CH_UNKN, CH_00E4, CH_010B, CH_0109, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_UNKN, CH_00F1, CH_00F2, CH_00F3, CH_00F4, CH_0121, CH_00F6, CH_00F7, CH_011D, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_016D, CH_015D, CH_02D9, +/* ISO8859_4 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_0104, CH_0138, CH_0156, CH_00A4, CH_0128, CH_013B, CH_00A7, CH_00A8, CH_0160, CH_0112, CH_0122, CH_0166, CH_00AD, CH_017D, CH_00AF, +/* B0 */ CH_00B0, CH_0105, CH_02DB, CH_0157, CH_00B4, CH_0129, CH_013C, CH_02C7, CH_00B8, CH_0161, CH_0113, CH_0123, CH_0167, CH_014A, CH_017E, CH_014B, +/* C0 */ CH_0100, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_012E, CH_010C, CH_00C9, CH_0118, CH_00CB, CH_0116, CH_00CD, CH_00CE, CH_012A, +/* D0 */ CH_0110, CH_0145, CH_014C, CH_0136, CH_00D4, CH_00D5, CH_00D6, CH_00D7, CH_00D8, CH_0172, CH_00DA, CH_00DB, CH_00DC, CH_0168, CH_016A, CH_00DF, +/* E0 */ CH_0101, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_012F, CH_010D, CH_00E9, CH_0119, CH_00EB, CH_0117, CH_00ED, CH_00EE, CH_012B, +/* F0 */ CH_0111, CH_0146, CH_014D, CH_0137, CH_00F4, CH_00F5, CH_00F6, CH_00F7, CH_00F8, CH_0173, CH_00FA, CH_00FB, CH_00FC, CH_0169, CH_016B, CH_02D9, +/* ISO8859_9 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_00A1, CH_00A2, CH_00A3, CH_00A4, CH_00A5, CH_00A6, CH_00A7, CH_00A8, CH_00A9, CH_00AA, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_00AF, +/* B0 */ CH_00B0, CH_00B1, CH_00B2, CH_00B3, CH_00B4, CH_00B5, CH_00B6, CH_00B7, CH_00B8, CH_00B9, CH_00BA, CH_00BB, CH_00BC, CH_00BD, CH_00BE, CH_00BF, +/* C0 */ CH_00C0, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_011E, CH_00D1, CH_00D2, CH_00D3, CH_00D4, CH_00D5, CH_00D6, CH_00D7, CH_00D8, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_0130, CH_015E, CH_00DF, +/* E0 */ CH_00E0, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_011F, CH_00F1, CH_00F2, CH_00F3, CH_00F4, CH_00F5, CH_00F6, CH_00F7, CH_00F8, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_0131, CH_015F, CH_00FF, +/* ISO8859_10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_0104, CH_0112, CH_0122, CH_012A, CH_0128, CH_0136, CH_00A7, CH_013B, CH_0110, CH_0160, CH_0166, CH_017D, CH_00AD, CH_016A, CH_014A, +/* B0 */ CH_00B0, CH_0105, CH_0113, CH_0123, CH_012B, CH_0129, CH_0137, CH_00B7, CH_013C, CH_0111, CH_0161, CH_0167, CH_017E, CH_UNKN, CH_016B, CH_014B, +/* C0 */ CH_0100, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_012E, CH_010C, CH_00C9, CH_0118, CH_00CB, CH_0116, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_00D0, CH_0145, CH_014C, CH_00D3, CH_00D4, CH_00D5, CH_00D6, CH_0168, CH_00D8, CH_0172, CH_00DA, CH_00DB, CH_00DC, CH_00DD, CH_00DE, CH_00DF, +/* E0 */ CH_0101, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_012F, CH_010D, CH_00E9, CH_0119, CH_00EB, CH_0117, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_00F0, CH_0146, CH_014D, CH_00F3, CH_00F4, CH_00F5, CH_00F6, CH_0169, CH_00F8, CH_0173, CH_00FA, CH_00FB, CH_00FC, CH_00FD, CH_00FE, CH_0138, +/* ISO8859_13 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_UNKN, CH_00A2, CH_00A3, CH_00A4, CH_UNKN, CH_00A6, CH_00A7, CH_00D8, CH_00A9, CH_0156, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_00C6, +/* B0 */ CH_00B0, CH_00B1, CH_00B2, CH_00B3, CH_UNKN, CH_00B5, CH_00B6, CH_00B7, CH_00F8, CH_00B9, CH_0157, CH_00BB, CH_00BC, CH_00BD, CH_00BE, CH_00E6, +/* C0 */ CH_0104, CH_012E, CH_0100, CH_0106, CH_00C4, CH_00C5, CH_0118, CH_0112, CH_010C, CH_00C9, CH_0179, CH_0116, CH_0122, CH_0136, CH_012A, CH_013B, +/* D0 */ CH_0160, CH_0143, CH_0145, CH_00D3, CH_014C, CH_00D5, CH_00D6, CH_00D7, CH_0172, CH_0141, CH_015A, CH_016A, CH_00DC, CH_017B, CH_017D, CH_00DF, +/* E0 */ CH_0105, CH_012F, CH_0101, CH_0107, CH_00E4, CH_00E5, CH_0119, CH_0113, CH_010D, CH_00E9, CH_017A, CH_0117, CH_0123, CH_0137, CH_012B, CH_013C, +/* F0 */ CH_0161, CH_0144, CH_0146, CH_00F3, CH_014D, CH_00F5, CH_00F6, CH_00F7, CH_0173, CH_0142, CH_015B, CH_016B, CH_00FC, CH_017C, CH_017E, CH_UNKN, +/* ISO8859_15 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_00A1, CH_00A2, CH_00A3, CH_UNKN, CH_00A5, CH_0160, CH_00A7, CH_0161, CH_00A9, CH_00AA, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_00AF, +/* B0 */ CH_00B0, CH_00B1, CH_00B2, CH_00B3, CH_017D, CH_00B5, CH_00B6, CH_00B7, CH_017E, CH_00B9, CH_00BA, CH_00BB, CH_0152, CH_0153, CH_0178, CH_00BF, +/* C0 */ CH_00C0, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_00D0, CH_00D1, CH_00D2, CH_00D3, CH_00D4, CH_00D5, CH_00D6, CH_00D7, CH_00D8, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_00DD, CH_00DE, CH_00DF, +/* E0 */ CH_00E0, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_00F0, CH_00F1, CH_00F2, CH_00F3, CH_00F4, CH_00F5, CH_00F6, CH_00F7, CH_00F8, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_00FD, CH_00FE, CH_00FF, +/* ISO8859_16 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* A0 */ CH_00A0, CH_0104, CH_0105, CH_0141, CH_UNKN, CH_UNKN, CH_0160, CH_00A7, CH_0161, CH_00A9, CH_UNKN, CH_00AB, CH_0179, CH_00AD, CH_017A, CH_017B, +/* B0 */ CH_00B0, CH_00B1, CH_010C, CH_0142, CH_017D, CH_UNKN, CH_00B6, CH_00B7, CH_017E, CH_010D, CH_UNKN, CH_00BB, CH_0152, CH_0153, CH_0178, CH_017C, +/* C0 */ CH_00C0, CH_00C1, CH_00C2, CH_0102, CH_00C4, CH_0106, CH_00C6, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* D0 */ CH_0110, CH_0143, CH_00D2, CH_00D3, CH_00D4, CH_0150, CH_00D6, CH_015A, CH_0170, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_0118, CH_UNKN, CH_00DF, +/* E0 */ CH_00E0, CH_00E1, CH_00E2, CH_0103, CH_00E4, CH_0107, CH_00E6, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* F0 */ CH_0111, CH_0144, CH_00F2, CH_00F3, CH_00F4, CH_0151, CH_00F6, CH_015B, CH_0171, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_0119, CH_UNKN, CH_00FF, +/* CP1250 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_0160, CH_UNKN, CH_015A, CH_0164, CH_017D, CH_0179, +/* 90 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_0161, CH_UNKN, CH_015B, CH_0165, CH_017E, CH_017A, +/* A0 */ CH_00A0, CH_02C7, CH_02D8, CH_0141, CH_00A4, CH_0104, CH_00A6, CH_00A7, CH_00A8, CH_00A9, CH_015E, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_017B, +/* B0 */ CH_00B0, CH_00B1, CH_02DB, CH_0142, CH_00B4, CH_00B5, CH_00B6, CH_00B7, CH_00B8, CH_0105, CH_015F, CH_00BB, CH_013D, CH_02DD, CH_013E, CH_017C, +/* C0 */ CH_0154, CH_00C1, CH_00C2, CH_0102, CH_00C4, CH_0139, CH_0106, CH_00C7, CH_010C, CH_00C9, CH_0118, CH_00CB, CH_011A, CH_00CD, CH_00CE, CH_010E, +/* D0 */ CH_0110, CH_0143, CH_0147, CH_00D3, CH_00D4, CH_0150, CH_00D6, CH_00D7, CH_0158, CH_016E, CH_00DA, CH_0170, CH_00DC, CH_00DD, CH_0162, CH_00DF, +/* E0 */ CH_0155, CH_00E1, CH_00E2, CH_0103, CH_00E4, CH_013A, CH_0107, CH_00E7, CH_010D, CH_00E9, CH_0119, CH_00EB, CH_011B, CH_00ED, CH_00EE, CH_010F, +/* F0 */ CH_0111, CH_0144, CH_0148, CH_00F3, CH_00F4, CH_0151, CH_00F6, CH_00F7, CH_0159, CH_016F, CH_00FA, CH_0171, CH_00FC, CH_00FD, CH_0163, CH_02D9, +/* CP852 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 80 */ CH_00C7, CH_00FC, CH_00E9, CH_00E2, CH_00E4, CH_016F, CH_0107, CH_00E7, CH_0142, CH_00EB, CH_0150, CH_0151, CH_00EE, CH_0179, CH_00C4, CH_0106, +/* 90 */ CH_00C9, CH_0139, CH_013A, CH_00F4, CH_00F6, CH_013D, CH_013E, CH_015A, CH_015B, CH_00D6, CH_00DC, CH_0164, CH_0165, CH_0141, CH_00D7, CH_010D, +/* A0 */ CH_00E1, CH_00ED, CH_00F3, CH_00FA, CH_0104, CH_0105, CH_017D, CH_017E, CH_0118, CH_0119, CH_00AC, CH_017A, CH_010C, CH_015F, CH_00AB, CH_00BB, +/* B0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_00C1, CH_00C2, CH_011A, CH_015E, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_017B, CH_017C, CH_UNKN, +/* C0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_0102, CH_0103, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_00A4, +/* D0 */ CH_0111, CH_0110, CH_010E, CH_00CB, CH_010F, CH_0147, CH_00CD, CH_00CE, CH_011B, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_0162, CH_016E, CH_UNKN, +/* E0 */ CH_00D3, CH_00DF, CH_00D4, CH_0143, CH_0144, CH_0148, CH_0160, CH_0161, CH_0154, CH_00DA, CH_0155, CH_0170, CH_00FD, CH_00DD, CH_0163, CH_00B4, +/* F0 */ CH_00AD, CH_02DD, CH_02DB, CH_02C7, CH_02D8, CH_00A7, CH_00F7, CH_00B8, CH_00B0, CH_00A8, CH_02D9, CH_0171, CH_0158, CH_0159, CH_UNKN, CH_00A0, +}; + +uint8_t const * const UNI_TABLE[0x02DE] = { +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0000 */ CH_0000, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 0010 */ CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 0020 */ CH_0020, CH_0021, CH_0022, CH_0023, CH_0024, CH_0025, CH_0026, CH_0027, CH_0028, CH_0029, CH_002A, CH_002B, CH_002C, CH_002D, CH_002E, CH_002F, +/* 0030 */ CH_0030, CH_0031, CH_0032, CH_0033, CH_0034, CH_0035, CH_0036, CH_0037, CH_0038, CH_0039, CH_003A, CH_003B, CH_003C, CH_003D, CH_003E, CH_003F, +/* 0040 */ CH_0040, CH_0041, CH_0042, CH_0043, CH_0044, CH_0045, CH_0046, CH_0047, CH_0048, CH_0049, CH_004A, CH_004B, CH_004C, CH_004D, CH_004E, CH_004F, +/* 0050 */ CH_0050, CH_0051, CH_0052, CH_0053, CH_0054, CH_0055, CH_0056, CH_0057, CH_0058, CH_0059, CH_005A, CH_005B, CH_005C, CH_005D, CH_005E, CH_005F, +/* 0060 */ CH_0060, CH_0061, CH_0062, CH_0063, CH_0064, CH_0065, CH_0066, CH_0067, CH_0068, CH_0069, CH_006A, CH_006B, CH_006C, CH_006D, CH_006E, CH_006F, +/* 0070 */ CH_0070, CH_0071, CH_0072, CH_0073, CH_0074, CH_0075, CH_0076, CH_0077, CH_0078, CH_0079, CH_007A, CH_007B, CH_007C, CH_007D, CH_007E, CH_NULL, +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0080 */ CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 0090 */ CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, CH_NULL, +/* 00A0 */ CH_00A0, CH_00A1, CH_00A2, CH_00A3, CH_00A4, CH_00A5, CH_00A6, CH_00A7, CH_00A8, CH_00A9, CH_00AA, CH_00AB, CH_00AC, CH_00AD, CH_00AE, CH_00AF, +/* 00B0 */ CH_00B0, CH_00B1, CH_00B2, CH_00B3, CH_00B4, CH_00B5, CH_00B6, CH_00B7, CH_00B8, CH_00B9, CH_00BA, CH_00BB, CH_00BC, CH_00BD, CH_00BE, CH_00BF, +/* 00C0 */ CH_00C0, CH_00C1, CH_00C2, CH_00C3, CH_00C4, CH_00C5, CH_00C6, CH_00C7, CH_00C8, CH_00C9, CH_00CA, CH_00CB, CH_00CC, CH_00CD, CH_00CE, CH_00CF, +/* 00D0 */ CH_00D0, CH_00D1, CH_00D2, CH_00D3, CH_00D4, CH_00D5, CH_00D6, CH_00D7, CH_00D8, CH_00D9, CH_00DA, CH_00DB, CH_00DC, CH_00DD, CH_00DE, CH_00DF, +/* 00E0 */ CH_00E0, CH_00E1, CH_00E2, CH_00E3, CH_00E4, CH_00E5, CH_00E6, CH_00E7, CH_00E8, CH_00E9, CH_00EA, CH_00EB, CH_00EC, CH_00ED, CH_00EE, CH_00EF, +/* 00F0 */ CH_00F0, CH_00F1, CH_00F2, CH_00F3, CH_00F4, CH_00F5, CH_00F6, CH_00F7, CH_00F8, CH_00F9, CH_00FA, CH_00FB, CH_00FC, CH_00FD, CH_00FE, CH_00FF, +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0100 */ CH_0100, CH_0101, CH_0102, CH_0103, CH_0104, CH_0105, CH_0106, CH_0107, CH_0108, CH_0109, CH_010A, CH_010B, CH_010C, CH_010D, CH_010E, CH_010F, +/* 0110 */ CH_0110, CH_0111, CH_0112, CH_0113, CH_0114, CH_0115, CH_0116, CH_0117, CH_0118, CH_0119, CH_011A, CH_011B, CH_011C, CH_011D, CH_011E, CH_011F, +/* 0120 */ CH_0120, CH_0121, CH_0122, CH_0123, CH_0124, CH_0125, CH_0126, CH_0127, CH_0128, CH_0129, CH_012A, CH_012B, CH_012C, CH_012D, CH_012E, CH_012F, +/* 0130 */ CH_0130, CH_0131, CH_0132, CH_0133, CH_0134, CH_0135, CH_0136, CH_0137, CH_0138, CH_0139, CH_013A, CH_013B, CH_013C, CH_013D, CH_013E, CH_013F, +/* 0140 */ CH_0140, CH_0141, CH_0142, CH_0143, CH_0144, CH_0145, CH_0146, CH_0147, CH_0148, CH_UNKN, CH_014A, CH_014B, CH_014C, CH_014D, CH_014E, CH_014F, +/* 0150 */ CH_0150, CH_0151, CH_0152, CH_0153, CH_0154, CH_0155, CH_0156, CH_0157, CH_0158, CH_0159, CH_015A, CH_015B, CH_015C, CH_015D, CH_015E, CH_015F, +/* 0160 */ CH_0160, CH_0161, CH_0162, CH_0163, CH_0164, CH_0165, CH_0166, CH_0167, CH_0168, CH_0169, CH_016A, CH_016B, CH_016C, CH_016D, CH_016E, CH_016F, +/* 0170 */ CH_0170, CH_0171, CH_0172, CH_0173, CH_0174, CH_0175, CH_0176, CH_0177, CH_0178, CH_0179, CH_017A, CH_017B, CH_017C, CH_017D, CH_017E, CH_UNKN, +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0180 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0190 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01A0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01B0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01C0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01D0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01E0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 01F0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0200 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0210 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0220 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0230 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0240 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0250 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0260 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0270 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 0280 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 0290 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 02A0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 02B0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 02C0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_02C7, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, +/* 02D0 */ CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_UNKN, CH_02D8, CH_02D9, CH_UNKN, CH_02DB, CH_UNKN, CH_02DD, +}; + +const uint8_t KEYBOARD_PATTERN[0x05EC] = { +/* 0000 */ + 0, +/* 0020: ' ' */ +/* 00A0: ' ' */ + 1, + KEY_SPACE, +/* 0021: '!' */ +/* 00A1: '¡' */ + 1, + SKEY_EXCL, +/* 0022: '"' */ + 1, + SKEY_QUOT, +/* 0023: '#' */ + 2, + CODE_ALT, + XKEY_HASH, +/* 0024: '$' */ + 2, + CODE_ALT, + XKEY_DOLLAR, +/* 0025: '%' */ + 1, + SKEY_PERCENT, +/* 0026: '&' */ + 1, + SKEY_AMP, +/* 0027: ''' */ + 2, + CODE_ALT, + XKEY_QUOT, +/* 0028: '(' */ + 1, + SKEY_LPAREN, +/* 0029: ')' */ + 1, + SKEY_RPAREN, +/* 002A: '*' */ + 2, + CODE_ALT, + XKEY_STAR, +/* 002B: '+' */ + 1, + SKEY_PLUS, +/* 002C: ',' */ +/* 00B8: '¸' */ + 1, + KEY_COMA, +/* 002D: '-' */ +/* 00AD: '­' */ + 1, + KEY_MINUS, +/* 002E: '.' */ + 1, + KEY_DOT, +/* 002F: '/' */ + 1, + SKEY_SLASH, +/* 0030: '0' */ + 1, + KEY_0, +/* 0031: '1' */ + 1, + KEY_1, +/* 0032: '2' */ + 1, + KEY_2, +/* 0033: '3' */ + 1, + KEY_3, +/* 0034: '4' */ + 1, + KEY_4, +/* 0035: '5' */ + 1, + KEY_5, +/* 0036: '6' */ + 1, + KEY_6, +/* 0037: '7' */ + 1, + KEY_7, +/* 0038: '8' */ + 1, + KEY_8, +/* 0039: '9' */ + 1, + KEY_9, +/* 003A: ':' */ + 1, + SKEY_COLON, +/* 003B: ';' */ + 1, + SKEY_SEMI, +/* 003C: '<' */ + 2, + CODE_ALT, + XKEY_LT, +/* 003D: '=' */ + 1, + SKEY_EQ, +/* 003E: '>' */ + 2, + CODE_ALT, + XKEY_GT, +/* 003F: '?' */ +/* 00BF: '¿' */ + 1, + SKEY_QUEST, +/* 0040: '@' */ + 17, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_STEPLEFT, + SKEY_LPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_A, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_RPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, +/* 0041: 'A' */ + 1, + SKEY_A, +/* 0042: 'B' */ + 1, + SKEY_B, +/* 0043: 'C' */ + 1, + SKEY_C, +/* 0044: 'D' */ + 1, + SKEY_D, +/* 0045: 'E' */ + 1, + SKEY_E, +/* 0046: 'F' */ + 1, + SKEY_F, +/* 0047: 'G' */ + 1, + SKEY_G, +/* 0048: 'H' */ + 1, + SKEY_H, +/* 0049: 'I' */ + 1, + SKEY_I, +/* 004A: 'J' */ + 1, + SKEY_J, +/* 004B: 'K' */ +/* 0138: 'ĸ' */ + 1, + SKEY_K, +/* 004C: 'L' */ + 1, + SKEY_L, +/* 004D: 'M' */ + 1, + SKEY_M, +/* 004E: 'N' */ + 1, + SKEY_N, +/* 004F: 'O' */ + 1, + SKEY_O, +/* 0050: 'P' */ + 1, + SKEY_P, +/* 0051: 'Q' */ + 1, + SKEY_Q, +/* 0052: 'R' */ + 1, + SKEY_R, +/* 0053: 'S' */ + 1, + SKEY_S, +/* 0054: 'T' */ + 1, + SKEY_T, +/* 0055: 'U' */ + 1, + SKEY_U, +/* 0056: 'V' */ + 1, + SKEY_V, +/* 0057: 'W' */ + 1, + SKEY_W, +/* 0058: 'X' */ + 1, + SKEY_X, +/* 0059: 'Y' */ + 1, + SKEY_Y, +/* 005A: 'Z' */ + 1, + SKEY_Z, +/* 005B: '[' */ + 9, + SKEY_LPAREN, + CODE_HALFUP, + KEY_BACK, + KEY_MINUS, + KEY_BACK, + CODE_HALFDOWN, + CODE_HALFDOWN, + KEY_MINUS, + CODE_HALFUP, +/* 005C: '\' */ + 14, + KEY_MARGIN, + CODE_STEPLEFT, + SKEY_GRAVE, + KEY_SPACE, + CODE_HALFDOWN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_GRAVE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_HALFUP, +/* 005D: ']' */ + 9, + SKEY_RPAREN, + CODE_HALFUP, + KEY_BACK, + KEY_MINUS, + KEY_BACK, + CODE_HALFDOWN, + CODE_HALFDOWN, + KEY_MINUS, + CODE_HALFUP, +/* 005E: '^' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, +/* 005F: '_' */ + 1, + SKEY_UNDER, +/* 0060: '`' */ + 2, + SKEY_GRAVE, + KEY_SPACE, +/* 0061: 'a' */ + 1, + KEY_A, +/* 0062: 'b' */ + 1, + KEY_B, +/* 0063: 'c' */ + 1, + KEY_C, +/* 0064: 'd' */ + 1, + KEY_D, +/* 0065: 'e' */ + 1, + KEY_E, +/* 0066: 'f' */ + 1, + KEY_F, +/* 0067: 'g' */ + 1, + KEY_G, +/* 0068: 'h' */ + 1, + KEY_H, +/* 0069: 'i' */ +/* 0131: 'ı' */ + 1, + KEY_I, +/* 006A: 'j' */ + 1, + KEY_J, +/* 006B: 'k' */ + 1, + KEY_K, +/* 006C: 'l' */ + 1, + KEY_L, +/* 006D: 'm' */ + 1, + KEY_M, +/* 006E: 'n' */ + 1, + KEY_N, +/* 006F: 'o' */ + 1, + KEY_O, +/* 0070: 'p' */ + 1, + KEY_P, +/* 0071: 'q' */ + 1, + KEY_Q, +/* 0072: 'r' */ + 1, + KEY_R, +/* 0073: 's' */ + 1, + KEY_S, +/* 0074: 't' */ + 1, + KEY_T, +/* 0075: 'u' */ + 1, + KEY_U, +/* 0076: 'v' */ + 1, + KEY_V, +/* 0077: 'w' */ + 1, + KEY_W, +/* 0078: 'x' */ +/* 00D7: '×' */ + 1, + KEY_X, +/* 0079: 'y' */ + 1, + KEY_Y, +/* 007A: 'z' */ + 1, + KEY_Z, +/* 007B: '{' */ + 4, + SKEY_LPAREN, + KEY_BACK, + CODE_ALT, + XKEY_LT, +/* 007C: '|' */ +/* 00A6: '¦' */ + 7, + CODE_ALT, + XKEY_QUOT, + KEY_BACK, + CODE_HALFDOWN, + CODE_ALT, + XKEY_QUOT, + CODE_HALFUP, +/* 007D: '}' */ + 4, + SKEY_RPAREN, + KEY_BACK, + CODE_ALT, + XKEY_GT, +/* 007E: '~' */ + 12, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 00A2: '¢' */ + 9, + KEY_C, + KEY_BACK, + CODE_ALT, + XKEY_QUOT, + KEY_BACK, + CODE_HALFDOWN, + CODE_ALT, + XKEY_QUOT, + CODE_HALFUP, +/* 00A3: '£' */ + 2, + CODE_ALT, + XKEY_POUND, +/* 00A4: '¤' */ + 3, + KEY_O, + KEY_BACK, + KEY_X, +/* 00A5: 'Â¥' */ + 3, + SKEY_Y, + KEY_BACK, + SKEY_EQ, +/* 00A7: '§' */ + 1, + SKEY_PARAG, +/* 00A8: '¨' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + KEY_SPACE, +/* 00A9: '©' */ + 17, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_STEPLEFT, + SKEY_LPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + SKEY_C, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_RPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, +/* 00AA: 'ª' */ + 5, + CODE_HALFUP, + KEY_A, + CODE_HALFDOWN, + KEY_BACK, + KEY_MINUS, +/* 00AB: '«' */ + 11, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_ALT, + XKEY_LT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + KEY_MARGIN, + CODE_ALT, + XKEY_LT, + CODE_STEPLEFT, +/* 00AC: '¬' */ + 12, + KEY_MINUS, + CODE_HALFDOWN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + CODE_ALT, + XKEY_QUOT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_HALFUP, +/* 00AE: '®' */ + 17, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_STEPLEFT, + SKEY_LPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + SKEY_R, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_RPAREN, + CODE_STEPLEFT, + CODE_STEPLEFT, +/* 00AF: '¯' */ + 3, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 00B0: '°' */ + 2, + CODE_ALT, + XKEY_DEGREE, +/* 00B1: '±' */ + 3, + SKEY_PLUS, + KEY_BACK, + SKEY_UNDER, +/* 00B2: '²' */ + 3, + CODE_HALFUP, + KEY_2, + CODE_HALFDOWN, +/* 00B3: '³' */ + 3, + CODE_HALFUP, + KEY_3, + CODE_HALFDOWN, +/* 00B4: '´' */ + 2, + KEY_ACUTE, + KEY_SPACE, +/* 00B5: 'µ' */ + 14, + KEY_U, + CODE_HALFDOWN, + KEY_BACK, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_ALT, + XKEY_QUOT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_SPACE, + CODE_HALFUP, +/* 00B6: '¶' */ + 3, + SKEY_P, + KEY_BACK, + SKEY_I, +/* 00B7: '·' */ +/* 02D9: '˙' */ + 3, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 00B9: '¹' */ + 3, + CODE_HALFUP, + KEY_1, + CODE_HALFDOWN, +/* 00BA: 'º' */ + 4, + CODE_ALT, + XKEY_DEGREE, + KEY_BACK, + KEY_MINUS, +/* 00BB: '»' */ + 12, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_ALT, + XKEY_GT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + CODE_ALT, + XKEY_GT, + CODE_STEPLEFT, +/* 00BC: '¼' */ + 9, + CODE_HALFUP, + KEY_1, + CODE_HALFDOWN, + KEY_BACK, + KEY_MINUS, + KEY_BACK, + CODE_HALFDOWN, + KEY_4, + CODE_HALFUP, +/* 00BD: '½' */ + 9, + CODE_HALFUP, + KEY_1, + CODE_HALFDOWN, + KEY_BACK, + KEY_MINUS, + KEY_BACK, + CODE_HALFDOWN, + KEY_2, + CODE_HALFUP, +/* 00BE: '¾' */ + 9, + CODE_HALFUP, + KEY_3, + CODE_HALFDOWN, + KEY_BACK, + KEY_MINUS, + KEY_BACK, + CODE_HALFDOWN, + KEY_4, + CODE_HALFUP, +/* 00C0: 'À' */ + 2, + SKEY_GRAVE, + SKEY_A, +/* 00C1: 'Á' */ + 2, + KEY_ACUTE, + SKEY_A, +/* 00C2: 'Â' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_A, +/* 00C3: 'Ã' */ +/* 0100: 'Ā' */ + 5, + SKEY_A, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 00C4: 'Ä' */ + 1, + SKEY_AE, +/* 00C5: 'Å' */ + 5, + SKEY_A, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 00C6: 'Æ' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + SKEY_A, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_E, + CODE_STEPLEFT, +/* 00C7: 'Ç' */ + 3, + SKEY_C, + KEY_BACK, + KEY_COMA, +/* 00C8: 'È' */ + 2, + SKEY_GRAVE, + SKEY_E, +/* 00C9: 'É' */ + 2, + KEY_ACUTE, + SKEY_E, +/* 00CA: 'Ê' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_E, +/* 00CB: 'Ë' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + SKEY_E, +/* 00CC: 'Ì' */ + 2, + SKEY_GRAVE, + SKEY_I, +/* 00CD: 'Í' */ + 2, + KEY_ACUTE, + SKEY_I, +/* 00CE: 'Î' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_I, +/* 00CF: 'Ï' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + SKEY_I, +/* 00D0: 'Ð' */ +/* 0110: 'Đ' */ + 9, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_MINUS, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + SKEY_D, +/* 00D1: 'Ñ' */ + 5, + SKEY_N, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 00D2: 'Ò' */ + 2, + SKEY_GRAVE, + SKEY_O, +/* 00D3: 'Ó' */ + 2, + KEY_ACUTE, + SKEY_O, +/* 00D4: 'Ô' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_O, +/* 00D5: 'Õ' */ +/* 014C: 'Ō' */ + 5, + SKEY_O, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 00D6: 'Ö' */ + 1, + SKEY_OE, +/* 00D8: 'Ø' */ + 3, + SKEY_O, + KEY_BACK, + SKEY_SLASH, +/* 00D9: 'Ù' */ + 2, + SKEY_GRAVE, + SKEY_U, +/* 00DA: 'Ú' */ + 2, + KEY_ACUTE, + SKEY_U, +/* 00DB: 'Û' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_U, +/* 00DC: 'Ü' */ + 1, + SKEY_UE, +/* 00DD: 'Ý' */ + 2, + KEY_ACUTE, + SKEY_Y, +/* 00DE: 'Þ' */ +/* 00FE: 'þ' */ + 3, + KEY_P, + KEY_BACK, + KEY_B, +/* 00DF: 'ß' */ + 1, + KEY_SS, +/* 00E0: 'à' */ + 2, + SKEY_GRAVE, + KEY_A, +/* 00E1: 'á' */ + 2, + KEY_ACUTE, + KEY_A, +/* 00E2: 'â' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_A, +/* 00E3: 'ã' */ + 14, + KEY_A, + KEY_BACK, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 00E4: 'ä' */ + 1, + KEY_AE, +/* 00E5: 'Ã¥' */ + 4, + KEY_A, + KEY_BACK, + CODE_ALT, + XKEY_DEGREE, +/* 00E6: 'æ' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_A, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_E, + CODE_STEPLEFT, +/* 00E7: 'ç' */ + 3, + KEY_C, + KEY_BACK, + KEY_COMA, +/* 00E8: 'è' */ + 2, + SKEY_GRAVE, + KEY_E, +/* 00E9: 'é' */ + 2, + KEY_ACUTE, + KEY_E, +/* 00EA: 'ê' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_E, +/* 00EB: 'ë' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + KEY_E, +/* 00EC: 'ì' */ + 2, + SKEY_GRAVE, + KEY_I, +/* 00ED: 'í' */ + 2, + KEY_ACUTE, + KEY_I, +/* 00EE: 'î' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_I, +/* 00EF: 'ï' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + KEY_I, +/* 00F0: 'ð' */ +/* 0111: 'đ' */ + 5, + KEY_D, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 00F1: 'ñ' */ + 14, + KEY_N, + KEY_BACK, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 00F2: 'ò' */ + 2, + SKEY_GRAVE, + KEY_O, +/* 00F3: 'ó' */ + 2, + KEY_ACUTE, + KEY_O, +/* 00F4: 'ô' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_O, +/* 00F5: 'õ' */ + 14, + KEY_O, + KEY_BACK, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 00F6: 'ö' */ + 1, + KEY_OE, +/* 00F7: '÷' */ + 3, + SKEY_COLON, + KEY_BACK, + KEY_MINUS, +/* 00F8: 'ø' */ + 3, + KEY_O, + KEY_BACK, + SKEY_SLASH, +/* 00F9: 'ù' */ + 2, + SKEY_GRAVE, + KEY_U, +/* 00FA: 'ú' */ + 2, + KEY_ACUTE, + KEY_U, +/* 00FB: 'û' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_U, +/* 00FC: 'ü' */ + 1, + KEY_UE, +/* 00FD: 'ý' */ + 2, + KEY_ACUTE, + KEY_Y, +/* 00FF: 'ÿ' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + KEY_Y, +/* 0101: 'ā' */ + 5, + KEY_A, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0102: 'Ă' */ + 5, + SKEY_GRAVE, + SKEY_A, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0103: 'ă' */ + 5, + SKEY_GRAVE, + KEY_A, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0104: 'Ą' */ + 9, + SKEY_A, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0105: 'ą' */ + 9, + KEY_A, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0106: 'Ć' */ + 2, + KEY_ACUTE, + SKEY_C, +/* 0107: 'ć' */ + 2, + KEY_ACUTE, + KEY_C, +/* 0108: 'Ĉ' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_C, +/* 0109: 'ĉ' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_C, +/* 010A: 'Ċ' */ + 5, + SKEY_C, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 010B: 'ċ' */ + 5, + KEY_C, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 010C: 'Č' */ + 5, + SKEY_GRAVE, + SKEY_C, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 010D: 'č' */ + 5, + SKEY_GRAVE, + KEY_C, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 010E: 'Ď' */ + 5, + SKEY_GRAVE, + SKEY_D, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 010F: 'ď' */ + 5, + SKEY_GRAVE, + KEY_D, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0112: 'Ē' */ + 5, + SKEY_E, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0113: 'ē' */ + 5, + KEY_E, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0114: 'Ĕ' */ +/* 011A: 'Ě' */ + 5, + SKEY_GRAVE, + SKEY_E, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0115: 'ĕ' */ +/* 011B: 'ě' */ + 5, + SKEY_GRAVE, + KEY_E, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0116: 'Ė' */ + 5, + SKEY_E, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0117: 'ė' */ + 5, + KEY_E, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0118: 'Ę' */ + 9, + SKEY_E, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0119: 'ę' */ + 9, + KEY_E, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 011C: 'Ĝ' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_G, +/* 011D: 'ĝ' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_G, +/* 011E: 'Ğ' */ + 5, + SKEY_GRAVE, + SKEY_G, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 011F: 'ğ' */ + 5, + SKEY_GRAVE, + KEY_G, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0120: 'Ä ' */ + 5, + SKEY_G, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0121: 'Ä¡' */ + 5, + KEY_G, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0122: 'Ä¢' */ + 3, + SKEY_G, + KEY_BACK, + KEY_COMA, +/* 0123: 'Ä£' */ + 3, + KEY_G, + KEY_BACK, + KEY_COMA, +/* 0124: 'Ĥ' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_H, +/* 0125: 'Ä¥' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_H, +/* 0126: 'Ħ' */ + 5, + SKEY_H, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0127: 'ħ' */ + 5, + KEY_H, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0128: 'Ĩ' */ +/* 012A: 'Ī' */ + 5, + SKEY_I, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0129: 'Ä©' */ + 14, + KEY_I, + KEY_BACK, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 012B: 'Ä«' */ + 5, + KEY_I, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 012C: 'Ĭ' */ + 5, + SKEY_GRAVE, + SKEY_I, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 012D: 'Ä­' */ + 5, + SKEY_GRAVE, + KEY_I, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 012E: 'Ä®' */ + 9, + SKEY_I, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 012F: 'į' */ + 9, + KEY_I, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0130: 'Ä°' */ + 5, + SKEY_I, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0132: 'IJ' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + SKEY_I, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_J, + CODE_STEPLEFT, +/* 0133: 'ij' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_I, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_J, + CODE_STEPLEFT, +/* 0134: 'Ä´' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_J, +/* 0135: 'ĵ' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_J, +/* 0136: 'Ķ' */ + 3, + SKEY_K, + KEY_BACK, + KEY_COMA, +/* 0137: 'Ä·' */ + 3, + KEY_K, + KEY_BACK, + KEY_COMA, +/* 0139: 'Ĺ' */ + 2, + KEY_ACUTE, + SKEY_L, +/* 013A: 'ĺ' */ + 2, + KEY_ACUTE, + KEY_L, +/* 013B: 'Ä»' */ + 3, + SKEY_L, + KEY_BACK, + KEY_COMA, +/* 013C: 'ļ' */ + 3, + KEY_L, + KEY_BACK, + KEY_COMA, +/* 013D: 'Ľ' */ + 5, + SKEY_L, + KEY_BACK, + CODE_HALFUP, + KEY_COMA, + CODE_HALFDOWN, +/* 013E: 'ľ' */ + 11, + KEY_L, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + CODE_HALFUP, + KEY_MARGIN, + KEY_COMA, + CODE_HALFDOWN, + CODE_STEPLEFT, +/* 013F: 'Ä¿' */ + 5, + SKEY_L, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0140: 'ŀ' */ + 11, + KEY_L, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + CODE_HALFUP, + KEY_MARGIN, + KEY_DOT, + CODE_HALFDOWN, + CODE_STEPLEFT, +/* 0141: 'Ł' */ + 3, + SKEY_L, + KEY_BACK, + KEY_MINUS, +/* 0142: 'ł' */ + 3, + KEY_L, + KEY_BACK, + KEY_MINUS, +/* 0143: 'Ń' */ + 2, + KEY_ACUTE, + SKEY_N, +/* 0144: 'ń' */ + 2, + KEY_ACUTE, + KEY_N, +/* 0145: 'Ņ' */ + 3, + SKEY_N, + KEY_BACK, + KEY_COMA, +/* 0146: 'ņ' */ + 3, + KEY_N, + KEY_BACK, + KEY_COMA, +/* 0147: 'Ň' */ + 5, + SKEY_GRAVE, + SKEY_N, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0148: 'ň' */ + 5, + SKEY_GRAVE, + KEY_N, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 014A: 'Ŋ' */ + 9, + SKEY_N, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 014B: 'ŋ' */ + 9, + KEY_N, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 014D: 'ō' */ + 5, + KEY_O, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 014E: 'Ŏ' */ + 5, + SKEY_GRAVE, + SKEY_O, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 014F: 'ŏ' */ + 5, + SKEY_GRAVE, + KEY_O, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0150: 'Ő' */ + 14, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + KEY_BACK, + SKEY_O, +/* 0151: 'ő' */ + 14, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + KEY_BACK, + KEY_O, +/* 0152: 'Œ' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + SKEY_O, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + SKEY_E, + CODE_STEPLEFT, +/* 0153: 'œ' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_O, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_E, + CODE_STEPLEFT, +/* 0154: 'Ŕ' */ + 2, + KEY_ACUTE, + SKEY_R, +/* 0155: 'ŕ' */ + 2, + KEY_ACUTE, + KEY_R, +/* 0156: 'Ŗ' */ + 3, + SKEY_R, + KEY_BACK, + KEY_COMA, +/* 0157: 'ŗ' */ + 3, + KEY_R, + KEY_BACK, + KEY_COMA, +/* 0158: 'Ř' */ + 5, + SKEY_GRAVE, + SKEY_R, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0159: 'ř' */ + 5, + SKEY_GRAVE, + KEY_R, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 015A: 'Ś' */ + 2, + KEY_ACUTE, + SKEY_S, +/* 015B: 'ś' */ + 2, + KEY_ACUTE, + KEY_S, +/* 015C: 'Ŝ' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_S, +/* 015D: 'ŝ' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_S, +/* 015E: 'Ş' */ + 3, + SKEY_S, + KEY_BACK, + KEY_COMA, +/* 015F: 'ş' */ + 3, + KEY_S, + KEY_BACK, + KEY_COMA, +/* 0160: 'Å ' */ + 5, + SKEY_GRAVE, + SKEY_S, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0161: 'Å¡' */ + 5, + SKEY_GRAVE, + KEY_S, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0162: 'Å¢' */ + 3, + SKEY_T, + KEY_BACK, + KEY_COMA, +/* 0163: 'Å£' */ + 3, + KEY_T, + KEY_BACK, + KEY_COMA, +/* 0164: 'Ť' */ + 5, + SKEY_GRAVE, + SKEY_T, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 0165: 'Å¥' */ + 11, + KEY_T, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + CODE_HALFUP, + KEY_MARGIN, + KEY_COMA, + CODE_HALFDOWN, + CODE_STEPLEFT, +/* 0166: 'Ŧ' */ + 3, + SKEY_T, + KEY_BACK, + KEY_MINUS, +/* 0167: 'ŧ' */ + 3, + KEY_T, + KEY_BACK, + KEY_MINUS, +/* 0168: 'Ũ' */ +/* 016A: 'Ū' */ + 5, + SKEY_U, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 0169: 'Å©' */ + 14, + KEY_U, + KEY_BACK, + CODE_ALT, + XKEY_CARET, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* 016B: 'Å«' */ + 5, + KEY_U, + KEY_BACK, + CODE_HALFUP, + KEY_MINUS, + CODE_HALFDOWN, +/* 016C: 'Ŭ' */ + 5, + SKEY_GRAVE, + SKEY_U, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 016D: 'Å­' */ + 5, + SKEY_GRAVE, + KEY_U, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 016E: 'Å®' */ + 5, + SKEY_U, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 016F: 'ů' */ + 5, + KEY_U, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 0170: 'Å°' */ + 14, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + KEY_BACK, + SKEY_U, +/* 0171: 'ű' */ + 14, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + KEY_BACK, + KEY_U, +/* 0172: 'Ų' */ + 9, + SKEY_U, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0173: 'ų' */ + 9, + KEY_U, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 0174: 'Å´' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_W, +/* 0175: 'ŵ' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_W, +/* 0176: 'Ŷ' */ + 3, + CODE_ALT, + XKEY_CARET, + SKEY_Y, +/* 0177: 'Å·' */ + 3, + CODE_ALT, + XKEY_CARET, + KEY_Y, +/* 0178: 'Ÿ' */ + 3, + CODE_ALT, + XKEY_UMLAUT, + SKEY_Y, +/* 0179: 'Ź' */ + 10, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + SKEY_Z, +/* 017A: 'ź' */ + 2, + KEY_ACUTE, + KEY_Z, +/* 017B: 'Å»' */ + 3, + SKEY_Z, + KEY_BACK, + KEY_MINUS, +/* 017C: 'ż' */ + 5, + KEY_Z, + KEY_BACK, + CODE_HALFUP, + KEY_DOT, + CODE_HALFDOWN, +/* 017D: 'Ž' */ + 5, + SKEY_GRAVE, + SKEY_Z, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 017E: 'ž' */ + 5, + SKEY_GRAVE, + KEY_Z, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 02C7: 'ˇ' */ +/* 02D8: '˘' */ + 5, + SKEY_GRAVE, + KEY_SPACE, + KEY_BACK, + KEY_ACUTE, + KEY_SPACE, +/* 02DB: '˛' */ + 9, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_COMA, + CODE_STEPLEFT, +/* 02DD: '˝' */ + 12, + KEY_MARGIN, + CODE_STEPLEFT, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + KEY_ACUTE, + KEY_SPACE, + CODE_STEPLEFT, +/* FFFD: '�' */ + 19, + KEY_MARGIN, + CODE_STEPLEFT, + CODE_ALT, + XKEY_LT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + SKEY_QUEST, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT, + CODE_STEPLEFT_EXTRA, + KEY_MARGIN, + CODE_ALT, + XKEY_GT, + CODE_STEPLEFT, +}; + +const uint8_t KEYMAP_ISO8859_1[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0xA3, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0x00, + /* Ę */ [TCODE_E_] = 0x00, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0x00, + /* Å» */ [TCODE_Z_] = 0x00, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0x00, + /* Ą */ [TCODE_A_] = 0x00, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_2[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xEA, + /* Ę */ [TCODE_E_] = 0xCA, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xBF, + /* Å» */ [TCODE_Z_] = 0xAF, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xB1, + /* Ą */ [TCODE_A_] = 0xA1, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0xB6, + /* Ś */ [TCODE_S_] = 0xA6, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0xB6, + /* Ś */ [TCODE_D_] = 0xA6, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0xB3, + /* Ł */ [TCODE_L_] = 0xA3, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0xBC, + /* Ź */ [TCODE_Y_] = 0xAC, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0xE6, + /* Ć */ [TCODE_C_] = 0xC6, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0xF1, + /* Ń */ [TCODE_N_] = 0xD1, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_3[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0xA3, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0x00, + /* Ę */ [TCODE_E_] = 0x00, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xBF, + /* Å» */ [TCODE_Z_] = 0xAF, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0x00, + /* Ą */ [TCODE_A_] = 0x00, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_4[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xEA, + /* Ę */ [TCODE_E_] = 0xCA, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0x00, + /* Å» */ [TCODE_Z_] = 0x00, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0x00, + /* Ó */ [TCODE_O_] = 0x00, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xB1, + /* Ą */ [TCODE_A_] = 0xA1, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_9[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0xA3, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0x00, + /* Ę */ [TCODE_E_] = 0x00, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0x00, + /* Å» */ [TCODE_Z_] = 0x00, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0x00, + /* Ą */ [TCODE_A_] = 0x00, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_10[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0x00, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0x00, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xEA, + /* Ę */ [TCODE_E_] = 0xCA, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0x00, + /* Å» */ [TCODE_Z_] = 0x00, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xB1, + /* Ą */ [TCODE_A_] = 0xA1, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_13[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0xA3, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0x00, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0x00, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xE6, + /* Ę */ [TCODE_E_] = 0xC6, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xFD, + /* Å» */ [TCODE_Z_] = 0xDD, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xE0, + /* Ą */ [TCODE_A_] = 0xC0, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0xFA, + /* Ś */ [TCODE_S_] = 0xDA, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0xFA, + /* Ś */ [TCODE_D_] = 0xDA, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0xF9, + /* Ł */ [TCODE_L_] = 0xD9, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0xEA, + /* Ź */ [TCODE_Y_] = 0xCA, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0xE3, + /* Ć */ [TCODE_C_] = 0xC3, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0xF1, + /* Ń */ [TCODE_N_] = 0xD1, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_15[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0xA3, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0x00, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0x00, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0x00, + /* Ę */ [TCODE_E_] = 0x00, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0x00, + /* Å» */ [TCODE_Z_] = 0x00, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0x00, + /* Ą */ [TCODE_A_] = 0x00, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x00, + /* Ś */ [TCODE_S_] = 0x00, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x00, + /* Ś */ [TCODE_D_] = 0x00, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x00, + /* Ł */ [TCODE_L_] = 0x00, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x00, + /* Ź */ [TCODE_Y_] = 0x00, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x00, + /* Ć */ [TCODE_C_] = 0x00, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0x00, + /* Ń */ [TCODE_N_] = 0x00, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_ISO8859_16[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0x00, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0x00, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xFD, + /* Ę */ [TCODE_E_] = 0xDD, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xBF, + /* Å» */ [TCODE_Z_] = 0xAF, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xA2, + /* Ą */ [TCODE_A_] = 0xA1, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0xF7, + /* Ś */ [TCODE_S_] = 0xD7, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0xF7, + /* Ś */ [TCODE_D_] = 0xD7, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0xB3, + /* Ł */ [TCODE_L_] = 0xA3, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0xAE, + /* Ź */ [TCODE_Y_] = 0xAC, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0xE5, + /* Ć */ [TCODE_C_] = 0xC5, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0xF1, + /* Ń */ [TCODE_N_] = 0xD1, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_CP1250[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xA7, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xDF, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xB0, + /* ´ */ [KEY_ACUTE] = 0xB4, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xA8, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xEA, + /* Ę */ [TCODE_E_] = 0xCA, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xBF, + /* Å» */ [TCODE_Z_] = 0xAF, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xF3, + /* Ó */ [TCODE_O_] = 0xD3, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0xFC, + /* Ü */ [SKEY_UE] = 0xDC, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xB9, + /* Ą */ [TCODE_A_] = 0xA5, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x9C, + /* Ś */ [TCODE_S_] = 0x8C, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x9C, + /* Ś */ [TCODE_D_] = 0x8C, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0xB3, + /* Ł */ [TCODE_L_] = 0xA3, + /* ö */ [KEY_OE] = 0xF6, + /* Ö */ [SKEY_OE] = 0xD6, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0xE4, + /* Ä */ [SKEY_AE] = 0xC4, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0x9F, + /* Ź */ [TCODE_Y_] = 0x8F, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0xE6, + /* Ć */ [TCODE_C_] = 0xC6, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0xF1, + /* Ń */ [TCODE_N_] = 0xD1, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint8_t KEYMAP_CP852[0x0100] = { + [0 ... 0xff] = 0x00, + /* @ */ [TKEY_AT] = 0x40, + /* ~ */ [TKEY_TILDE] = 0x7E, + [TCODE_ESC] = 0x1B, + /* 1 */ [KEY_1] = 0x31, + /* ! */ [SKEY_EXCL] = 0x21, + /* < */ [TCODE_LT] = 0x3C, + /* < */ [TCODE_LT_] = 0x3C, + /* 2 */ [KEY_2] = 0x32, + /* " */ [SKEY_QUOT] = 0x22, + /* > */ [TCODE_GT] = 0x3E, + /* > */ [TCODE_GT_] = 0x3E, + /* 3 */ [KEY_3] = 0x33, + /* § */ [SKEY_PARAG] = 0xF5, + /* ' */ [TCODE_QUOT] = 0x27, + /* ' */ [TCODE_QUOT_] = 0x27, + /* 4 */ [KEY_4] = 0x34, + /* + */ [SKEY_PLUS] = 0x2B, + /* 5 */ [KEY_5] = 0x35, + /* % */ [SKEY_PERCENT] = 0x25, + /* 6 */ [KEY_6] = 0x36, + /* & */ [SKEY_AMP] = 0x26, + /* 7 */ [KEY_7] = 0x37, + /* / */ [SKEY_SLASH] = 0x2F, + /* 8 */ [KEY_8] = 0x38, + /* ( */ [SKEY_LPAREN] = 0x28, + /* 9 */ [KEY_9] = 0x39, + /* ) */ [SKEY_RPAREN] = 0x29, + /* 0 */ [KEY_0] = 0x30, + /* = */ [SKEY_EQ] = 0x3D, + /* # */ [TCODE_HASH] = 0x23, + /* $ */ [TCODE_DOLLAR] = 0x24, + /* ß */ [KEY_SS] = 0xE1, + /* ? */ [SKEY_QUEST] = 0x3F, + /* £ */ [TCODE_POUND] = 0x00, + /* ° */ [TCODE_DEGREE] = 0xF8, + /* ´ */ [KEY_ACUTE] = 0xEF, + /* ` */ [SKEY_GRAVE] = 0x60, + /* ^ */ [TCODE_DASH] = 0x5E, + /* ¨ */ [TCODE_UMLAUT] = 0xF9, + [KEY_BACK] = 0x08, + [KEY_TAB] = 0x09, + /* q */ [KEY_Q] = 0x71, + /* Q */ [SKEY_Q] = 0x51, + /* w */ [KEY_W] = 0x77, + /* W */ [SKEY_W] = 0x57, + /* e */ [KEY_E] = 0x65, + /* E */ [SKEY_E] = 0x45, + /* ę */ [TCODE_E] = 0xA9, + /* Ę */ [TCODE_E_] = 0xA8, + /* r */ [KEY_R] = 0x72, + /* R */ [SKEY_R] = 0x52, + /* t */ [KEY_T] = 0x74, + /* T */ [SKEY_T] = 0x54, + /* z */ [KEY_Z] = 0x7A, + /* Z */ [SKEY_Z] = 0x5A, + /* ż */ [TCODE_Z] = 0xBE, + /* Å» */ [TCODE_Z_] = 0xBD, + /* u */ [KEY_U] = 0x75, + /* U */ [SKEY_U] = 0x55, + /* i */ [KEY_I] = 0x69, + /* I */ [SKEY_I] = 0x49, + /* o */ [KEY_O] = 0x6F, + /* O */ [SKEY_O] = 0x4F, + /* ó */ [TCODE_O] = 0xA2, + /* Ó */ [TCODE_O_] = 0xE0, + /* p */ [KEY_P] = 0x70, + /* P */ [SKEY_P] = 0x50, + /* ü */ [KEY_UE] = 0x81, + /* Ü */ [SKEY_UE] = 0x9A, + /* \ */ [TCODE_BSLASH] = 0x5C, + /* | */ [TCODE_WALL] = 0x7C, + [KEY_RETURN] = 0x0D, + [SKEY_RETURN] = 0x0D, + /* a */ [KEY_A] = 0x61, + /* A */ [SKEY_A] = 0x41, + /* ą */ [TCODE_A] = 0xA5, + /* Ą */ [TCODE_A_] = 0xA4, + /* s */ [KEY_S] = 0x73, + /* S */ [SKEY_S] = 0x53, + /* ś */ [TCODE_S] = 0x98, + /* Ś */ [TCODE_S_] = 0x97, + /* d */ [KEY_D] = 0x64, + /* D */ [SKEY_D] = 0x44, + /* ś */ [TCODE_D] = 0x98, + /* Ś */ [TCODE_D_] = 0x97, + /* f */ [KEY_F] = 0x66, + /* F */ [SKEY_F] = 0x46, + /* g */ [KEY_G] = 0x67, + /* G */ [SKEY_G] = 0x47, + /* h */ [KEY_H] = 0x68, + /* H */ [SKEY_H] = 0x48, + /* j */ [KEY_J] = 0x6A, + /* J */ [SKEY_J] = 0x4A, + /* k */ [KEY_K] = 0x6B, + /* K */ [SKEY_K] = 0x4B, + /* l */ [KEY_L] = 0x6C, + /* L */ [SKEY_L] = 0x4C, + /* ł */ [TCODE_L] = 0x88, + /* Ł */ [TCODE_L_] = 0x9D, + /* ö */ [KEY_OE] = 0x94, + /* Ö */ [SKEY_OE] = 0x99, + /* [ */ [TCODE_LSQBR] = 0x5B, + /* { */ [TCODE_LCURL] = 0x7B, + /* ä */ [KEY_AE] = 0x84, + /* Ä */ [SKEY_AE] = 0x8E, + /* ] */ [TCODE_RSQBR] = 0x5D, + /* } */ [TCODE_RCURL] = 0x7D, + /* y */ [KEY_Y] = 0x79, + /* Y */ [SKEY_Y] = 0x59, + /* ź */ [TCODE_Y] = 0xAB, + /* Ź */ [TCODE_Y_] = 0x8D, + /* x */ [KEY_X] = 0x78, + /* X */ [SKEY_X] = 0x58, + /* c */ [KEY_C] = 0x63, + /* C */ [SKEY_C] = 0x43, + /* ć */ [TCODE_C] = 0x86, + /* Ć */ [TCODE_C_] = 0x8F, + /* v */ [KEY_V] = 0x76, + /* V */ [SKEY_V] = 0x56, + /* b */ [KEY_B] = 0x62, + /* B */ [SKEY_B] = 0x42, + /* n */ [KEY_N] = 0x6E, + /* N */ [SKEY_N] = 0x4E, + /* ń */ [TCODE_N] = 0xE4, + /* Ń */ [TCODE_N_] = 0xE3, + /* m */ [KEY_M] = 0x6D, + /* M */ [SKEY_M] = 0x4D, + /* , */ [KEY_COMA] = 0x2C, + /* ; */ [SKEY_SEMI] = 0x3B, + /* . */ [KEY_DOT] = 0x2E, + /* : */ [SKEY_COLON] = 0x3A, + /* - */ [KEY_MINUS] = 0x2D, + /* _ */ [SKEY_UNDER] = 0x5F, + /* * */ [TCODE_STAR] = 0x2A, + /* */ [KEY_SPACE] = 0x20, + /* */ [SKEY_SPACE] = 0x20, + [KEY_ERASE1] = 0x7F, + [KEY_ERASEW] = 0x7F, +}; +const uint16_t KEYMAP_UNI[0x0100] = { + [0 ... 0xff] = 0x0000, + /* @ */ [TKEY_AT] = 0x0040, + /* ~ */ [TKEY_TILDE] = 0x007E, + [TCODE_ESC] = 0x001B, + /* 1 */ [KEY_1] = 0x0031, + /* ! */ [SKEY_EXCL] = 0x0021, + /* < */ [TCODE_LT] = 0x003C, + /* < */ [TCODE_LT_] = 0x003C, + /* 2 */ [KEY_2] = 0x0032, + /* " */ [SKEY_QUOT] = 0x0022, + /* > */ [TCODE_GT] = 0x003E, + /* > */ [TCODE_GT_] = 0x003E, + /* 3 */ [KEY_3] = 0x0033, + /* § */ [SKEY_PARAG] = 0x00A7, + /* ' */ [TCODE_QUOT] = 0x0027, + /* ' */ [TCODE_QUOT_] = 0x0027, + /* 4 */ [KEY_4] = 0x0034, + /* + */ [SKEY_PLUS] = 0x002B, + /* 5 */ [KEY_5] = 0x0035, + /* % */ [SKEY_PERCENT] = 0x0025, + /* 6 */ [KEY_6] = 0x0036, + /* & */ [SKEY_AMP] = 0x0026, + /* 7 */ [KEY_7] = 0x0037, + /* / */ [SKEY_SLASH] = 0x002F, + /* 8 */ [KEY_8] = 0x0038, + /* ( */ [SKEY_LPAREN] = 0x0028, + /* 9 */ [KEY_9] = 0x0039, + /* ) */ [SKEY_RPAREN] = 0x0029, + /* 0 */ [KEY_0] = 0x0030, + /* = */ [SKEY_EQ] = 0x003D, + /* # */ [TCODE_HASH] = 0x0023, + /* $ */ [TCODE_DOLLAR] = 0x0024, + /* ß */ [KEY_SS] = 0x00DF, + /* ? */ [SKEY_QUEST] = 0x003F, + /* £ */ [TCODE_POUND] = 0x00A3, + /* ° */ [TCODE_DEGREE] = 0x00B0, + /* ´ */ [KEY_ACUTE] = 0x00B4, + /* ` */ [SKEY_GRAVE] = 0x0060, + /* ^ */ [TCODE_DASH] = 0x005E, + /* ¨ */ [TCODE_UMLAUT] = 0x00A8, + [KEY_BACK] = 0x0008, + [KEY_TAB] = 0x0009, + /* q */ [KEY_Q] = 0x0071, + /* Q */ [SKEY_Q] = 0x0051, + /* w */ [KEY_W] = 0x0077, + /* W */ [SKEY_W] = 0x0057, + /* e */ [KEY_E] = 0x0065, + /* E */ [SKEY_E] = 0x0045, + /* ę */ [TCODE_E] = 0x0119, + /* Ę */ [TCODE_E_] = 0x0118, + /* r */ [KEY_R] = 0x0072, + /* R */ [SKEY_R] = 0x0052, + /* t */ [KEY_T] = 0x0074, + /* T */ [SKEY_T] = 0x0054, + /* z */ [KEY_Z] = 0x007A, + /* Z */ [SKEY_Z] = 0x005A, + /* ż */ [TCODE_Z] = 0x017C, + /* Å» */ [TCODE_Z_] = 0x017B, + /* u */ [KEY_U] = 0x0075, + /* U */ [SKEY_U] = 0x0055, + /* i */ [KEY_I] = 0x0069, + /* I */ [SKEY_I] = 0x0049, + /* o */ [KEY_O] = 0x006F, + /* O */ [SKEY_O] = 0x004F, + /* ó */ [TCODE_O] = 0x00F3, + /* Ó */ [TCODE_O_] = 0x00D3, + /* p */ [KEY_P] = 0x0070, + /* P */ [SKEY_P] = 0x0050, + /* ü */ [KEY_UE] = 0x00FC, + /* Ü */ [SKEY_UE] = 0x00DC, + /* \ */ [TCODE_BSLASH] = 0x005C, + /* | */ [TCODE_WALL] = 0x007C, + [KEY_RETURN] = 0x000D, + [SKEY_RETURN] = 0x000D, + /* a */ [KEY_A] = 0x0061, + /* A */ [SKEY_A] = 0x0041, + /* ą */ [TCODE_A] = 0x0105, + /* Ą */ [TCODE_A_] = 0x0104, + /* s */ [KEY_S] = 0x0073, + /* S */ [SKEY_S] = 0x0053, + /* ś */ [TCODE_S] = 0x015B, + /* Ś */ [TCODE_S_] = 0x015A, + /* d */ [KEY_D] = 0x0064, + /* D */ [SKEY_D] = 0x0044, + /* ś */ [TCODE_D] = 0x015B, + /* Ś */ [TCODE_D_] = 0x015A, + /* f */ [KEY_F] = 0x0066, + /* F */ [SKEY_F] = 0x0046, + /* g */ [KEY_G] = 0x0067, + /* G */ [SKEY_G] = 0x0047, + /* h */ [KEY_H] = 0x0068, + /* H */ [SKEY_H] = 0x0048, + /* j */ [KEY_J] = 0x006A, + /* J */ [SKEY_J] = 0x004A, + /* k */ [KEY_K] = 0x006B, + /* K */ [SKEY_K] = 0x004B, + /* l */ [KEY_L] = 0x006C, + /* L */ [SKEY_L] = 0x004C, + /* ł */ [TCODE_L] = 0x0142, + /* Ł */ [TCODE_L_] = 0x0141, + /* ö */ [KEY_OE] = 0x00F6, + /* Ö */ [SKEY_OE] = 0x00D6, + /* [ */ [TCODE_LSQBR] = 0x005B, + /* { */ [TCODE_LCURL] = 0x007B, + /* ä */ [KEY_AE] = 0x00E4, + /* Ä */ [SKEY_AE] = 0x00C4, + /* ] */ [TCODE_RSQBR] = 0x005D, + /* } */ [TCODE_RCURL] = 0x007D, + /* y */ [KEY_Y] = 0x0079, + /* Y */ [SKEY_Y] = 0x0059, + /* ź */ [TCODE_Y] = 0x017A, + /* Ź */ [TCODE_Y_] = 0x0179, + /* x */ [KEY_X] = 0x0078, + /* X */ [SKEY_X] = 0x0058, + /* c */ [KEY_C] = 0x0063, + /* C */ [SKEY_C] = 0x0043, + /* ć */ [TCODE_C] = 0x0107, + /* Ć */ [TCODE_C_] = 0x0106, + /* v */ [KEY_V] = 0x0076, + /* V */ [SKEY_V] = 0x0056, + /* b */ [KEY_B] = 0x0062, + /* B */ [SKEY_B] = 0x0042, + /* n */ [KEY_N] = 0x006E, + /* N */ [SKEY_N] = 0x004E, + /* ń */ [TCODE_N] = 0x0144, + /* Ń */ [TCODE_N_] = 0x0143, + /* m */ [KEY_M] = 0x006D, + /* M */ [SKEY_M] = 0x004D, + /* , */ [KEY_COMA] = 0x002C, + /* ; */ [SKEY_SEMI] = 0x003B, + /* . */ [KEY_DOT] = 0x002E, + /* : */ [SKEY_COLON] = 0x003A, + /* - */ [KEY_MINUS] = 0x002D, + /* _ */ [SKEY_UNDER] = 0x005F, + /* * */ [TCODE_STAR] = 0x002A, + /* */ [KEY_SPACE] = 0x0020, + /* */ [SKEY_SPACE] = 0x0020, + [KEY_ERASE1] = 0x007F, + [KEY_ERASEW] = 0x007F, +}; diff --git a/keyboard-patterns.h b/keyboard-patterns.h new file mode 100644 index 0000000..38a0940 --- /dev/null +++ b/keyboard-patterns.h @@ -0,0 +1,380 @@ +/* file autogenerated from keyboard-patterns.txt. do not edit - will be overwritten */ + +#include +#include "keyboard.h" + +extern const uint8_t ENC_C1[0x0B]; +extern uint8_t const * const CH_TABLE[0x0600]; +extern uint8_t const * const UNI_TABLE[0x02DE]; +extern const uint8_t KEYBOARD_PATTERN[0x05EC]; +extern const uint8_t KEYMAP_ISO8859_1[0x0100]; +extern const uint8_t KEYMAP_ISO8859_2[0x0100]; +extern const uint8_t KEYMAP_ISO8859_3[0x0100]; +extern const uint8_t KEYMAP_ISO8859_4[0x0100]; +extern const uint8_t KEYMAP_ISO8859_9[0x0100]; +extern const uint8_t KEYMAP_ISO8859_10[0x0100]; +extern const uint8_t KEYMAP_ISO8859_13[0x0100]; +extern const uint8_t KEYMAP_ISO8859_15[0x0100]; +extern const uint8_t KEYMAP_ISO8859_16[0x0100]; +extern const uint8_t KEYMAP_CP1250[0x0100]; +extern const uint8_t KEYMAP_CP852[0x0100]; +extern const uint16_t KEYMAP_UNI[0x0100]; +extern uint8_t const * const * const CH_LIST[0x0B]; +extern uint8_t const * const KEYMAP_LIST[0x0B]; + +#define ENC_ISO8859_1 0x00 +#define ENC_ISO8859_2 0x01 +#define ENC_ISO8859_3 0x02 +#define ENC_ISO8859_4 0x03 +#define ENC_ISO8859_9 0x04 +#define ENC_ISO8859_10 0x05 +#define ENC_ISO8859_13 0x06 +#define ENC_ISO8859_15 0x07 +#define ENC_ISO8859_16 0x08 +#define ENC_CP1250 0x09 +#define ENC_CP852 0x0A +#define N_ENC 0x0B +#define ENC_UNI 0x80 + +#define CH_ASCII CH_TABLE +#define CH_ISO8859_1 ((uint8_t const * const *)(&(CH_TABLE[0x0000]))) +#define CH_ISO8859_2 ((uint8_t const * const *)(&(CH_TABLE[0x0080]))) +#define CH_ISO8859_3 ((uint8_t const * const *)(&(CH_TABLE[0x0100]))) +#define CH_ISO8859_4 ((uint8_t const * const *)(&(CH_TABLE[0x0180]))) +#define CH_ISO8859_9 ((uint8_t const * const *)(&(CH_TABLE[0x0200]))) +#define CH_ISO8859_10 ((uint8_t const * const *)(&(CH_TABLE[0x0280]))) +#define CH_ISO8859_13 ((uint8_t const * const *)(&(CH_TABLE[0x0300]))) +#define CH_ISO8859_15 ((uint8_t const * const *)(&(CH_TABLE[0x0380]))) +#define CH_ISO8859_16 ((uint8_t const * const *)(&(CH_TABLE[0x0400]))) +#define CH_CP1250 ((uint8_t const * const *)(&(CH_TABLE[0x0480]))) +#define CH_CP852 ((uint8_t const * const *)(&(CH_TABLE[0x0500]))) + +#define CH_LIMIT 0x2DE + +#define CH_0000 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0000]))) +#define CH_0020 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0001]))) /* */ +#define CH_0021 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0003]))) /* ! */ +#define CH_0022 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0005]))) /* " */ +#define CH_0023 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0007]))) /* # */ +#define CH_0024 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x000A]))) /* $ */ +#define CH_0025 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x000D]))) /* % */ +#define CH_0026 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x000F]))) /* & */ +#define CH_0027 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0011]))) /* ' */ +#define CH_0028 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0014]))) /* ( */ +#define CH_0029 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0016]))) /* ) */ +#define CH_002A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0018]))) /* * */ +#define CH_002B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x001B]))) /* + */ +#define CH_002C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x001D]))) /* , */ +#define CH_002D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x001F]))) /* - */ +#define CH_002E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0021]))) /* . */ +#define CH_002F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0023]))) /* / */ +#define CH_0030 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0025]))) /* 0 */ +#define CH_0031 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0027]))) /* 1 */ +#define CH_0032 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0029]))) /* 2 */ +#define CH_0033 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x002B]))) /* 3 */ +#define CH_0034 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x002D]))) /* 4 */ +#define CH_0035 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x002F]))) /* 5 */ +#define CH_0036 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0031]))) /* 6 */ +#define CH_0037 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0033]))) /* 7 */ +#define CH_0038 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0035]))) /* 8 */ +#define CH_0039 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0037]))) /* 9 */ +#define CH_003A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0039]))) /* : */ +#define CH_003B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x003B]))) /* ; */ +#define CH_003C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x003D]))) /* < */ +#define CH_003D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0040]))) /* = */ +#define CH_003E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0042]))) /* > */ +#define CH_003F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0045]))) /* ? */ +#define CH_0040 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0047]))) /* @ */ +#define CH_0041 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0059]))) /* A */ +#define CH_0042 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x005B]))) /* B */ +#define CH_0043 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x005D]))) /* C */ +#define CH_0044 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x005F]))) /* D */ +#define CH_0045 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0061]))) /* E */ +#define CH_0046 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0063]))) /* F */ +#define CH_0047 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0065]))) /* G */ +#define CH_0048 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0067]))) /* H */ +#define CH_0049 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0069]))) /* I */ +#define CH_004A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x006B]))) /* J */ +#define CH_004B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x006D]))) /* K */ +#define CH_004C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x006F]))) /* L */ +#define CH_004D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0071]))) /* M */ +#define CH_004E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0073]))) /* N */ +#define CH_004F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0075]))) /* O */ +#define CH_0050 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0077]))) /* P */ +#define CH_0051 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0079]))) /* Q */ +#define CH_0052 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x007B]))) /* R */ +#define CH_0053 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x007D]))) /* S */ +#define CH_0054 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x007F]))) /* T */ +#define CH_0055 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0081]))) /* U */ +#define CH_0056 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0083]))) /* V */ +#define CH_0057 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0085]))) /* W */ +#define CH_0058 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0087]))) /* X */ +#define CH_0059 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0089]))) /* Y */ +#define CH_005A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x008B]))) /* Z */ +#define CH_005B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x008D]))) /* [ */ +#define CH_005C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0097]))) /* \ */ +#define CH_005D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00A6]))) /* ] */ +#define CH_005E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00B0]))) /* ^ */ +#define CH_005F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00B4]))) /* _ */ +#define CH_0060 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00B6]))) /* ` */ +#define CH_0061 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00B9]))) /* a */ +#define CH_0062 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00BB]))) /* b */ +#define CH_0063 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00BD]))) /* c */ +#define CH_0064 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00BF]))) /* d */ +#define CH_0065 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C1]))) /* e */ +#define CH_0066 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C3]))) /* f */ +#define CH_0067 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C5]))) /* g */ +#define CH_0068 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C7]))) /* h */ +#define CH_0069 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C9]))) /* i */ +#define CH_006A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00CB]))) /* j */ +#define CH_006B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00CD]))) /* k */ +#define CH_006C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00CF]))) /* l */ +#define CH_006D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00D1]))) /* m */ +#define CH_006E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00D3]))) /* n */ +#define CH_006F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00D5]))) /* o */ +#define CH_0070 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00D7]))) /* p */ +#define CH_0071 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00D9]))) /* q */ +#define CH_0072 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00DB]))) /* r */ +#define CH_0073 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00DD]))) /* s */ +#define CH_0074 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00DF]))) /* t */ +#define CH_0075 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E1]))) /* u */ +#define CH_0076 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E3]))) /* v */ +#define CH_0077 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E5]))) /* w */ +#define CH_0078 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E7]))) /* x */ +#define CH_0079 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E9]))) /* y */ +#define CH_007A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00EB]))) /* z */ +#define CH_007B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00ED]))) /* { */ +#define CH_007C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00F2]))) /* | */ +#define CH_007D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00FA]))) /* } */ +#define CH_007E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00FF]))) /* ~ */ +#define CH_00A0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0001]))) /*   */ +#define CH_00A1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0003]))) /* ¡ */ +#define CH_00A2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x010C]))) /* ¢ */ +#define CH_00A3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0116]))) /* £ */ +#define CH_00A4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0119]))) /* ¤ */ +#define CH_00A5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x011D]))) /* Â¥ */ +#define CH_00A6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00F2]))) /* ¦ */ +#define CH_00A7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0121]))) /* § */ +#define CH_00A8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0123]))) /* ¨ */ +#define CH_00A9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0127]))) /* © */ +#define CH_00AA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0139]))) /* ª */ +#define CH_00AB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x013F]))) /* « */ +#define CH_00AC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x014B]))) /* ¬ */ +#define CH_00AD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x001F]))) /* ­ */ +#define CH_00AE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0158]))) /* ® */ +#define CH_00AF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x016A]))) /* ¯ */ +#define CH_00B0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x016E]))) /* ° */ +#define CH_00B1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0171]))) /* ± */ +#define CH_00B2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0175]))) /* ² */ +#define CH_00B3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0179]))) /* ³ */ +#define CH_00B4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x017D]))) /* ´ */ +#define CH_00B5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0180]))) /* µ */ +#define CH_00B6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x018F]))) /* ¶ */ +#define CH_00B7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0193]))) /* · */ +#define CH_00B8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x001D]))) /* ¸ */ +#define CH_00B9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0197]))) /* ¹ */ +#define CH_00BA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x019B]))) /* º */ +#define CH_00BB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01A0]))) /* » */ +#define CH_00BC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01AD]))) /* ¼ */ +#define CH_00BD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01B7]))) /* ½ */ +#define CH_00BE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01C1]))) /* ¾ */ +#define CH_00BF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0045]))) /* ¿ */ +#define CH_00C0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01CB]))) /* À */ +#define CH_00C1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01CE]))) /* Á */ +#define CH_00C2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01D1]))) /*  */ +#define CH_00C3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01D5]))) /* à */ +#define CH_00C4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01DB]))) /* Ä */ +#define CH_00C5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01DD]))) /* Å */ +#define CH_00C6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01E3]))) /* Æ */ +#define CH_00C7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01EE]))) /* Ç */ +#define CH_00C8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01F2]))) /* È */ +#define CH_00C9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01F5]))) /* É */ +#define CH_00CA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01F8]))) /* Ê */ +#define CH_00CB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01FC]))) /* Ë */ +#define CH_00CC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0200]))) /* Ì */ +#define CH_00CD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0203]))) /* Í */ +#define CH_00CE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0206]))) /* Î */ +#define CH_00CF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x020A]))) /* Ï */ +#define CH_00D0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x020E]))) /* Ð */ +#define CH_00D1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0218]))) /* Ñ */ +#define CH_00D2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x021E]))) /* Ò */ +#define CH_00D3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0221]))) /* Ó */ +#define CH_00D4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0224]))) /* Ô */ +#define CH_00D5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0228]))) /* Õ */ +#define CH_00D6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x022E]))) /* Ö */ +#define CH_00D7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00E7]))) /* × */ +#define CH_00D8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0230]))) /* Ø */ +#define CH_00D9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0234]))) /* Ù */ +#define CH_00DA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0237]))) /* Ú */ +#define CH_00DB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x023A]))) /* Û */ +#define CH_00DC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x023E]))) /* Ü */ +#define CH_00DD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0240]))) /* Ý */ +#define CH_00DE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0243]))) /* Þ */ +#define CH_00DF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0247]))) /* ß */ +#define CH_00E0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0249]))) /* à */ +#define CH_00E1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x024C]))) /* á */ +#define CH_00E2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x024F]))) /* â */ +#define CH_00E3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0253]))) /* ã */ +#define CH_00E4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0262]))) /* ä */ +#define CH_00E5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0264]))) /* Ã¥ */ +#define CH_00E6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0269]))) /* æ */ +#define CH_00E7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0274]))) /* ç */ +#define CH_00E8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0278]))) /* è */ +#define CH_00E9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x027B]))) /* é */ +#define CH_00EA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x027E]))) /* ê */ +#define CH_00EB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0282]))) /* ë */ +#define CH_00EC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0286]))) /* ì */ +#define CH_00ED ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0289]))) /* í */ +#define CH_00EE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x028C]))) /* î */ +#define CH_00EF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0290]))) /* ï */ +#define CH_00F0 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0294]))) /* ð */ +#define CH_00F1 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x029A]))) /* ñ */ +#define CH_00F2 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02A9]))) /* ò */ +#define CH_00F3 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02AC]))) /* ó */ +#define CH_00F4 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02AF]))) /* ô */ +#define CH_00F5 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02B3]))) /* õ */ +#define CH_00F6 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02C2]))) /* ö */ +#define CH_00F7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02C4]))) /* ÷ */ +#define CH_00F8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02C8]))) /* ø */ +#define CH_00F9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02CC]))) /* ù */ +#define CH_00FA ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02CF]))) /* ú */ +#define CH_00FB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02D2]))) /* û */ +#define CH_00FC ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02D6]))) /* ü */ +#define CH_00FD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02D8]))) /* ý */ +#define CH_00FE ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0243]))) /* þ */ +#define CH_00FF ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02DB]))) /* ÿ */ +#define CH_0100 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x01D5]))) /* Ā */ +#define CH_0101 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02DF]))) /* ā */ +#define CH_0102 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02E5]))) /* Ă */ +#define CH_0103 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02EB]))) /* ă */ +#define CH_0104 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02F1]))) /* Ą */ +#define CH_0105 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x02FB]))) /* ą */ +#define CH_0106 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0305]))) /* Ć */ +#define CH_0107 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0308]))) /* ć */ +#define CH_0108 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x030B]))) /* Ĉ */ +#define CH_0109 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x030F]))) /* ĉ */ +#define CH_010A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0313]))) /* Ċ */ +#define CH_010B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0319]))) /* ċ */ +#define CH_010C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x031F]))) /* Č */ +#define CH_010D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0325]))) /* č */ +#define CH_010E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x032B]))) /* Ď */ +#define CH_010F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0331]))) /* ď */ +#define CH_0110 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x020E]))) /* Đ */ +#define CH_0111 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0294]))) /* đ */ +#define CH_0112 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0337]))) /* Ē */ +#define CH_0113 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x033D]))) /* ē */ +#define CH_0114 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0343]))) /* Ĕ */ +#define CH_0115 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0349]))) /* ĕ */ +#define CH_0116 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x034F]))) /* Ė */ +#define CH_0117 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0355]))) /* ė */ +#define CH_0118 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x035B]))) /* Ę */ +#define CH_0119 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0365]))) /* ę */ +#define CH_011A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0343]))) /* Ě */ +#define CH_011B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0349]))) /* ě */ +#define CH_011C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x036F]))) /* Ĝ */ +#define CH_011D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0373]))) /* ĝ */ +#define CH_011E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0377]))) /* Ğ */ +#define CH_011F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x037D]))) /* ğ */ +#define CH_0120 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0383]))) /* Ä  */ +#define CH_0121 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0389]))) /* Ä¡ */ +#define CH_0122 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x038F]))) /* Ä¢ */ +#define CH_0123 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0393]))) /* Ä£ */ +#define CH_0124 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0397]))) /* Ĥ */ +#define CH_0125 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x039B]))) /* Ä¥ */ +#define CH_0126 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x039F]))) /* Ħ */ +#define CH_0127 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03A5]))) /* ħ */ +#define CH_0128 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03AB]))) /* Ĩ */ +#define CH_0129 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03B1]))) /* Ä© */ +#define CH_012A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03AB]))) /* Ī */ +#define CH_012B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03C0]))) /* Ä« */ +#define CH_012C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03C6]))) /* Ĭ */ +#define CH_012D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03CC]))) /* Ä­ */ +#define CH_012E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03D2]))) /* Ä® */ +#define CH_012F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03DC]))) /* į */ +#define CH_0130 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03E6]))) /* Ä° */ +#define CH_0131 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x00C9]))) /* ı */ +#define CH_0132 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03EC]))) /* IJ */ +#define CH_0133 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x03F7]))) /* ij */ +#define CH_0134 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0402]))) /* Ä´ */ +#define CH_0135 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0406]))) /* ĵ */ +#define CH_0136 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x040A]))) /* Ķ */ +#define CH_0137 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x040E]))) /* Ä· */ +#define CH_0138 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x006D]))) /* ĸ */ +#define CH_0139 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0412]))) /* Ĺ */ +#define CH_013A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0415]))) /* ĺ */ +#define CH_013B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0418]))) /* Ä» */ +#define CH_013C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x041C]))) /* ļ */ +#define CH_013D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0420]))) /* Ľ */ +#define CH_013E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0426]))) /* ľ */ +#define CH_013F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0432]))) /* Ä¿ */ +#define CH_0140 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0438]))) /* ŀ */ +#define CH_0141 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0444]))) /* Ł */ +#define CH_0142 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0448]))) /* ł */ +#define CH_0143 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x044C]))) /* Ń */ +#define CH_0144 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x044F]))) /* ń */ +#define CH_0145 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0452]))) /* Ņ */ +#define CH_0146 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0456]))) /* ņ */ +#define CH_0147 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x045A]))) /* Ň */ +#define CH_0148 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0460]))) /* ň */ +#define CH_014A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0466]))) /* Ŋ */ +#define CH_014B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0470]))) /* ŋ */ +#define CH_014C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0228]))) /* Ō */ +#define CH_014D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x047A]))) /* ō */ +#define CH_014E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0480]))) /* Ŏ */ +#define CH_014F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0486]))) /* ŏ */ +#define CH_0150 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x048C]))) /* Ő */ +#define CH_0151 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x049B]))) /* ő */ +#define CH_0152 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04AA]))) /* Œ */ +#define CH_0153 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04B5]))) /* œ */ +#define CH_0154 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04C0]))) /* Ŕ */ +#define CH_0155 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04C3]))) /* ŕ */ +#define CH_0156 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04C6]))) /* Ŗ */ +#define CH_0157 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04CA]))) /* ŗ */ +#define CH_0158 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04CE]))) /* Ř */ +#define CH_0159 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04D4]))) /* ř */ +#define CH_015A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04DA]))) /* Ś */ +#define CH_015B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04DD]))) /* ś */ +#define CH_015C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04E0]))) /* Ŝ */ +#define CH_015D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04E4]))) /* ŝ */ +#define CH_015E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04E8]))) /* Ş */ +#define CH_015F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04EC]))) /* ş */ +#define CH_0160 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04F0]))) /* Å  */ +#define CH_0161 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04F6]))) /* Å¡ */ +#define CH_0162 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x04FC]))) /* Å¢ */ +#define CH_0163 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0500]))) /* Å£ */ +#define CH_0164 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0504]))) /* Ť */ +#define CH_0165 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x050A]))) /* Å¥ */ +#define CH_0166 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0516]))) /* Ŧ */ +#define CH_0167 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x051A]))) /* ŧ */ +#define CH_0168 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x051E]))) /* Ũ */ +#define CH_0169 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0524]))) /* Å© */ +#define CH_016A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x051E]))) /* Ū */ +#define CH_016B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0533]))) /* Å« */ +#define CH_016C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0539]))) /* Ŭ */ +#define CH_016D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x053F]))) /* Å­ */ +#define CH_016E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0545]))) /* Å® */ +#define CH_016F ((uint8_t const *) (&(KEYBOARD_PATTERN[0x054B]))) /* ů */ +#define CH_0170 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0551]))) /* Å° */ +#define CH_0171 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0560]))) /* ű */ +#define CH_0172 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x056F]))) /* Ų */ +#define CH_0173 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0579]))) /* ų */ +#define CH_0174 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0583]))) /* Å´ */ +#define CH_0175 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0587]))) /* ŵ */ +#define CH_0176 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x058B]))) /* Ŷ */ +#define CH_0177 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x058F]))) /* Å· */ +#define CH_0178 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0593]))) /* Ÿ */ +#define CH_0179 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0597]))) /* Ź */ +#define CH_017A ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05A2]))) /* ź */ +#define CH_017B ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05A5]))) /* Å» */ +#define CH_017C ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05A9]))) /* ż */ +#define CH_017D ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05AF]))) /* Ž */ +#define CH_017E ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05B5]))) /* ž */ +#define CH_02C7 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05BB]))) /* ˇ */ +#define CH_02D8 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05BB]))) /* ˘ */ +#define CH_02D9 ((uint8_t const *) (&(KEYBOARD_PATTERN[0x0193]))) /* ˙ */ +#define CH_02DB ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05C1]))) /* ˛ */ +#define CH_02DD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05CB]))) /* ˝ */ +#define CH_FFFD ((uint8_t const *) (&(KEYBOARD_PATTERN[0x05D8]))) /* � */ + +#define CH_NULL CH_0000 +#define CH_UNKN CH_FFFD diff --git a/keyboard-patterns.py b/keyboard-patterns.py new file mode 100755 index 0000000..012b33f --- /dev/null +++ b/keyboard-patterns.py @@ -0,0 +1,254 @@ +#!/usr/bin/python3 + +import sys +import re + +KEYB_DEF = 'keyboard.h' +REPLACEMENT = 0xFFFD + +mode = '' +encodings = ['ascii'] +sequences = {} +ch = 0 +sequence = [] +offsets = {} +reverse_offsets={} +max_ch = 0 +total_pattern=[] +encodings_upper = ['ASCII'] +key = '' +keyvalue = -1 +keymap = {} + +def add_sequence(): + global ch, max_ch, sequence + global offsets, reverse_offsets, sequences + global total_pattern + global key, keyvalue, keymap + + if len(sequence) != 0: + if (ch > max_ch) and (ch != REPLACEMENT): + max_ch = ch + for c in sequences: + if sequence == sequences[c]: + offsets[ch] = offsets[c] + reverse_offsets[offsets[c]].append(ch) + sequence = [] + return + sequences[ch] = sequence + offsets[ch] = len(total_pattern) + reverse_offsets[offsets[ch]] = [ch] + total_pattern.append(str(len(sequence))) + for p in sequence: + total_pattern.append(p) + sequence = [] + + if keyvalue >= 0: + keymap[key] = keyvalue + keyvalue = -1 + +sequences[0]=[] +offsets[0]=0 +reverse_offsets[0]=[0] +total_pattern.append('0') + +l = len(sys.argv) +if l>=4: + file_in = sys.argv[1] + file_h = sys.argv[2] + file_c = sys.argv[3] +else: + print('missing arguments.', file=sys.stderr) + +with open(file_in, 'rt', encoding='utf-8') as file: + for line in file: + i = line.find('#') + if i >= 0: + line = line[0:i] + line = line.strip() + + m = re.search('^([A-Za-z0-9_]+):$', line) + if m: + add_sequence() + t = m.group(1) + if t == 'encoding': + mode = 'encoding' + elif re.search('^[0-9A-Fa-f]+$', t): + mode = 'sequence' + ch = int(t, 16) + sequence = [] + elif re.search('^[0-9A-Z_]+$', t): + mode = 'key' + key = t + keyvalue = -1 + else: + mode = '' + elif line != '': + if mode == 'encoding': + encodings.append(line) + encodings_upper.append(line.upper().replace('-', '_')) + elif mode == 'sequence': + sequence.append(line) + elif mode == 'key': + if re.search('^([0-9A-Fa-f]){2,4}$', line): + keyvalue = int(line, 16) + elif len(line) == 1: + keyvalue = ord(line) + +add_sequence() +max_ch += 1 +B = [bytes([i]) for i in range (0x0, 0x100)] + +with open(file_h, 'wt', encoding='utf-8') as file: + print('/* file autogenerated from ' + file_in + '. do not edit - will be overwritten */', file=file) + print('', file=file) + print('#include ', file=file) + print('#include "'+KEYB_DEF+'"', file=file) + print('', file=file) + print('extern const uint8_t ENC_C1[0x%02X];' % (len(encodings)-1), file=file) + print('extern uint8_t const * const CH_TABLE[0x%04X];' % (len(encodings)*0x80), file=file) + print('extern uint8_t const * const UNI_TABLE[0x%04X];' % max_ch, file=file) + print(('extern const uint8_t KEYBOARD_PATTERN[0x%04X];' % len(total_pattern)), file=file) + for i, enc in enumerate(encodings): + if enc == 'ascii': + continue + print('extern const uint8_t KEYMAP_' + encodings_upper[i] + '[0x0100];', file=file) + print('extern const uint16_t KEYMAP_UNI[0x0100];', file=file) + print('extern uint8_t const * const * const CH_LIST[0x%02X];' % (len(encodings)-1), file=file) + print('extern uint8_t const * const KEYMAP_LIST[0x%02X];' % (len(encodings)-1), file=file) + + + print('', file=file) + + for i, enc in enumerate(encodings): + if enc == 'ascii': + continue + print('#define ENC_' + encodings_upper[i] + (' 0x%02X' % (i - 1)), file=file) + print('#define N_ENC 0x%02X' % (len(encodings)-1), file=file) + print('#define ENC_UNI 0x80', file=file) + print('', file=file) + + for i, enc in enumerate(encodings): + if i==0: + print ('#define CH_' + encodings_upper[i] + ' CH_TABLE', file=file) + else: + print ('#define CH_' + encodings_upper[i] + ' ((uint8_t const * const *)(&(CH_TABLE[0x%04X])))' % ((i-1) * 0x80), file=file) + + print('', file=file) + print('#define CH_LIMIT 0x%02X' % (max_ch), file=file) + print('', file=file) + + for off in sorted(offsets): + print(('#define CH_%04X ((uint8_t const *) (&(KEYBOARD_PATTERN[0x%04X])))' % (off, offsets[off])) + ((' /* ' + chr(off) + ' */') if ((off >= 0x20) and not (0x7f <= off <= 0x9f)) else ''), file=file) + + print('', file=file) + print('#define CH_NULL CH_0000', file=file) + print('#define CH_UNKN CH_%04X' % REPLACEMENT, file=file) + +with open(file_c, 'wt', encoding='utf-8') as file: + print('/* file autogenerated from ' + file_in + '. do not edit - will be overwritten */', file=file) + print('#include ', file=file) + print('#include "'+KEYB_DEF+'"', file=file) + print('#include "'+file_h+'"', file=file) + + print('', file=file) + + print('const uint8_t ENC_C1[0x%02X] = {' % (len(encodings)-1), file=file) + for enc in encodings: + if enc == 'ascii': + continue + print ('\t%d,' % int ('iso8859-' in enc), file=file) + print('};', file=file) + print('', file=file) + + print('uint8_t const * const * const CH_LIST[0x%02X] = {' % (len(encodings)-1), file=file) + for i, enc in enumerate(encodings): + if enc == 'ascii': + continue + print('\tCH_' + encodings_upper[i] + ',', file=file) + print('};', file=file) + print('', file=file) + + print('uint8_t const * const KEYMAP_LIST[0x%02X] = {' % (len(encodings)-1), file=file) + for i, enc in enumerate(encodings): + if enc == 'ascii': + continue + print('\tKEYMAP_' + encodings_upper[i] + ',', file=file) + print('};', file=file) + print('', file=file) + + print ('uint8_t const * const CH_TABLE[0x%04X] = {' % (len(encodings)*0x80), file=file) + for n, enc in enumerate(encodings): + enc_text = encodings_upper[n] + if len(enc_text) > 10: + enc_text = enc_text[0:10] + else: + enc_text += ' ' * (10 - len(enc_text)) + print('/* ' + enc_text + ' 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */', file=file) + for i in (range(0, 0x80, 0x10) if enc == 'ascii' else range(0x80, 0x100, 0x10)): + line = '/* %02X */' % i + for j in range(0, 0x10, 1): + c = i+j + t = B[c].decode(enc, errors='ignore') + if t == '': + line += ' CH_UNKN,' + else: + c = ord(t) + if c in offsets: + line += ' CH_%04X,' % c + else: + if (c < 0x20): #or (0x7f <= c <= 0x9f): + line += ' CH_NULL,' + else: + line += ' CH_UNKN,' + print(line, file=file) + print('};', file=file) + print('', file=file) + print ('uint8_t const * const UNI_TABLE[0x%04X] = {' % max_ch, file=file) + for i in range(0, max_ch, 0x10): + if i & 0x7f == 0: + print('/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */', file=file) + line = '/* %04X */' % i + for c in range (i, min(max_ch, i+0x10), 1): + if c in offsets: + line += ' CH_%04X,' % c + else: + if (c < 0x20) or (0x7f <= c <= 0x9f): + line += ' CH_NULL,' + else: + line += ' CH_UNKN,' + print(line, file=file) + print('};', file=file) + + print('', file=file) + + print(('const uint8_t KEYBOARD_PATTERN[0x%04X] = {' % len(total_pattern)), file=file) + for i, line in enumerate(total_pattern): + if i in reverse_offsets: + for c in reverse_offsets[i]: + print(('/* %04X' % c) + ((": '" + chr(c) + "'") if ((c >= 0x20) and not (0x7f <= c <= 0x9f)) else '') + ' */', file=file) + print('\t' + line + ',', file=file) + print('};', file=file) + + print('', file=file) + + for n, enc in enumerate(encodings): + if enc == 'ascii': + continue + print('const uint8_t KEYMAP_' + encodings_upper[n] + '[0x0100] = {', file=file) + print('\t[0 ... 0xff] = 0x00,', file=file) + for k in keymap: + c = keymap[k] + ch = chr(c) + ck = ch.encode(enc, errors='ignore') + ci = int.from_bytes(ck, 'little') + print ('\t' + (('/* ' + ch + ' */ ') if ((c >= 0x20) and not (0x7f <= c <= 0x9f)) else ' ') + '[' + k + ('] = 0x%02X,' % ci), file=file) + print('};', file=file) + print('const uint16_t KEYMAP_UNI[0x0100] = {', file=file) + print('\t[0 ... 0xff] = 0x0000,', file=file) + for k in keymap: + c = keymap[k] + ch = chr(c) + print ('\t' + (('/* ' + ch + ' */ ') if ((c >= 0x20) and not (0x7f <= c <= 0x9f)) else ' ') + '[' + k + ('] = 0x%04X,' % c), file=file) + print('};', file=file) + \ No newline at end of file diff --git a/keyboard-patterns.txt b/keyboard-patterns.txt new file mode 100644 index 0000000..7dd2349 --- /dev/null +++ b/keyboard-patterns.txt @@ -0,0 +1,1979 @@ +encoding: + iso8859-1 + iso8859-2 + iso8859-3 + iso8859-4 + iso8859-9 + iso8859-10 + iso8859-13 + iso8859-15 + iso8859-16 + cp1250 + cp852 + +0020: # ' ' + KEY_SPACE +0021: # '!' + SKEY_EXCL +0022: # '"' + SKEY_QUOT +0023: # '#' + CODE_ALT + XKEY_HASH +0024: # '$' + CODE_ALT + XKEY_DOLLAR +0025: # '%' + SKEY_PERCENT +0026: # '&' + SKEY_AMP +0027: # ''' + CODE_ALT + XKEY_QUOT +0028: # '(' + SKEY_LPAREN +0029: # ')' + SKEY_RPAREN +002A: # '*' + CODE_ALT + XKEY_STAR +002B: # '+' + SKEY_PLUS +002C: # ',' + KEY_COMA +002D: # '-' + KEY_MINUS +002E: # '.' + KEY_DOT +002F: # '/' + SKEY_SLASH +0030: # '0' + KEY_0 +0031: # '1' + KEY_1 +0032: # '2' + KEY_2 +0033: # '3' + KEY_3 +0034: # '4' + KEY_4 +0035: # '5' + KEY_5 +0036: # '6' + KEY_6 +0037: # '7' + KEY_7 +0038: # '8' + KEY_8 +0039: # '9' + KEY_9 +003A: # ':' + SKEY_COLON +003B: # ';' + SKEY_SEMI +003C: # '<' + CODE_ALT + XKEY_LT +003D: # '=' + SKEY_EQ +003E: # '>' + CODE_ALT + XKEY_GT +003F: # '?' + SKEY_QUEST +0040: # '@' + KEY_MARGIN + CODE_STEPLEFT + CODE_STEPLEFT + SKEY_LPAREN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_A + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_RPAREN + CODE_STEPLEFT + CODE_STEPLEFT +0041: # 'A' + SKEY_A +0042: # 'B' + SKEY_B +0043: # 'C' + SKEY_C +0044: # 'D' + SKEY_D +0045: # 'E' + SKEY_E +0046: # 'F' + SKEY_F +0047: # 'G' + SKEY_G +0048: # 'H' + SKEY_H +0049: # 'I' + SKEY_I +004A: # 'J' + SKEY_J +004B: # 'K' + SKEY_K +004C: # 'L' + SKEY_L +004D: # 'M' + SKEY_M +004E: # 'N' + SKEY_N +004F: # 'O' + SKEY_O +0050: # 'P' + SKEY_P +0051: # 'Q' + SKEY_Q +0052: # 'R' + SKEY_R +0053: # 'S' + SKEY_S +0054: # 'T' + SKEY_T +0055: # 'U' + SKEY_U +0056: # 'V' + SKEY_V +0057: # 'W' + SKEY_W +0058: # 'X' + SKEY_X +0059: # 'Y' + SKEY_Y +005A: # 'Z' + SKEY_Z +005B: # '[' + SKEY_LPAREN + CODE_HALFUP + KEY_BACK + KEY_MINUS + KEY_BACK + CODE_HALFDOWN + CODE_HALFDOWN + KEY_MINUS + CODE_HALFUP +005C: # '\' + KEY_MARGIN + CODE_STEPLEFT + SKEY_GRAVE + KEY_SPACE + CODE_HALFDOWN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_GRAVE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_HALFUP +005D: # ']' + SKEY_RPAREN + CODE_HALFUP + KEY_BACK + KEY_MINUS + KEY_BACK + CODE_HALFDOWN + CODE_HALFDOWN + KEY_MINUS + CODE_HALFUP +005E: # '^' + CODE_ALT + XKEY_CARET + KEY_SPACE +005F: # '_' + SKEY_UNDER +0060: # '`' + SKEY_GRAVE + KEY_SPACE +0061: # 'a' + KEY_A +0062: # 'b' + KEY_B +0063: # 'c' + KEY_C +0064: # 'd' + KEY_D +0065: # 'e' + KEY_E +0066: # 'f' + KEY_F +0067: # 'g' + KEY_G +0068: # 'h' + KEY_H +0069: # 'i' + KEY_I +006A: # 'j' + KEY_J +006B: # 'k' + KEY_K +006C: # 'l' + KEY_L +006D: # 'm' + KEY_M +006E: # 'n' + KEY_N +006F: # 'o' + KEY_O +0070: # 'p' + KEY_P +0071: # 'q' + KEY_Q +0072: # 'r' + KEY_R +0073: # 's' + KEY_S +0074: # 't' + KEY_T +0075: # 'u' + KEY_U +0076: # 'v' + KEY_V +0077: # 'w' + KEY_W +0078: # 'x' + KEY_X +0079: # 'y' + KEY_Y +007A: # 'z' + KEY_Z +007B: # '{' + SKEY_LPAREN + KEY_BACK + CODE_ALT + XKEY_LT +007C: # '|' + CODE_ALT + XKEY_QUOT + KEY_BACK + CODE_HALFDOWN + CODE_ALT + XKEY_QUOT + CODE_HALFUP +007D: # '}' + SKEY_RPAREN + KEY_BACK + CODE_ALT + XKEY_GT +007E: # '~' + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +007F: +0080: +0081: +0082: +0083: +0084: +0085: +0086: +0087: +0088: +0089: +008A: +008B: +008C: +008D: +008E: +008F: +0090: +0091: +0092: +0093: +0094: +0095: +0096: +0097: +0098: +0099: +009A: +009B: +009C: +009D: +009E: +009F: +00A0: # ' ' + KEY_SPACE +00A1: # '¡' + SKEY_EXCL +00A2: # '¢' + KEY_C + KEY_BACK + CODE_ALT + XKEY_QUOT + KEY_BACK + CODE_HALFDOWN + CODE_ALT + XKEY_QUOT + CODE_HALFUP +00A3: # '£' + CODE_ALT + XKEY_POUND +00A4: # '¤' + KEY_O + KEY_BACK + KEY_X +00A5: # 'Â¥' + SKEY_Y + KEY_BACK + SKEY_EQ +00A6: # '¦' + CODE_ALT + XKEY_QUOT + KEY_BACK + CODE_HALFDOWN + CODE_ALT + XKEY_QUOT + CODE_HALFUP +00A7: # '§' + SKEY_PARAG +00A8: # '¨' + CODE_ALT + XKEY_UMLAUT + KEY_SPACE +00A9: # '©' + KEY_MARGIN + CODE_STEPLEFT + CODE_STEPLEFT + SKEY_LPAREN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_C + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_RPAREN + CODE_STEPLEFT + CODE_STEPLEFT +00AA: # 'ª' + CODE_HALFUP + KEY_A + CODE_HALFDOWN + KEY_BACK + KEY_MINUS +00AB: # '«' + KEY_MARGIN + CODE_STEPLEFT + CODE_ALT + XKEY_LT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + KEY_MARGIN + CODE_ALT + XKEY_LT + CODE_STEPLEFT +00AC: # '¬' + KEY_MINUS + CODE_HALFDOWN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + CODE_ALT + XKEY_QUOT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_HALFUP +00AD: # '­' + KEY_MINUS +00AE: # '®' + KEY_MARGIN + CODE_STEPLEFT + CODE_STEPLEFT + SKEY_LPAREN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_R + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_RPAREN + CODE_STEPLEFT + CODE_STEPLEFT +00AF: # '¯' + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +00B0: # '°' + CODE_ALT + XKEY_DEGREE +00B1: # '±' + SKEY_PLUS + KEY_BACK + SKEY_UNDER +00B2: # '²' + CODE_HALFUP + KEY_2 + CODE_HALFDOWN +00B3: # '³' + CODE_HALFUP + KEY_3 + CODE_HALFDOWN +00B4: # '´' + KEY_ACUTE + KEY_SPACE +00B5: # 'µ' + KEY_U + CODE_HALFDOWN + KEY_BACK + KEY_MARGIN + CODE_STEPLEFT + CODE_STEPLEFT + CODE_ALT + XKEY_QUOT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_SPACE + CODE_HALFUP +00B6: # '¶' + SKEY_P + KEY_BACK + SKEY_I +00B7: # '·' + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +00B8: # '¸' + KEY_COMA +00B9: # '¹' + CODE_HALFUP + KEY_1 + CODE_HALFDOWN +00BA: # 'º' + CODE_ALT + XKEY_DEGREE + KEY_BACK + KEY_MINUS +00BB: # '»' + KEY_MARGIN + CODE_STEPLEFT + CODE_ALT + XKEY_GT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + CODE_ALT + XKEY_GT + CODE_STEPLEFT +00BC: # '¼' + CODE_HALFUP + KEY_1 + CODE_HALFDOWN + KEY_BACK + KEY_MINUS + KEY_BACK + CODE_HALFDOWN + KEY_4 + CODE_HALFUP +00BD: # '½' + CODE_HALFUP + KEY_1 + CODE_HALFDOWN + KEY_BACK + KEY_MINUS + KEY_BACK + CODE_HALFDOWN + KEY_2 + CODE_HALFUP +00BE: # '¾' + CODE_HALFUP + KEY_3 + CODE_HALFDOWN + KEY_BACK + KEY_MINUS + KEY_BACK + CODE_HALFDOWN + KEY_4 + CODE_HALFUP +00BF: # '¿' + SKEY_QUEST +00C0: # 'À' + SKEY_GRAVE + SKEY_A +00C1: # 'Á' + KEY_ACUTE + SKEY_A +00C2: # 'Â' + CODE_ALT + XKEY_CARET + SKEY_A +00C3: # 'Ã' + SKEY_A + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +00C4: # 'Ä' + SKEY_AE +00C5: # 'Å' + SKEY_A + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +00C6: # 'Æ' + KEY_MARGIN + CODE_STEPLEFT + SKEY_A + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_E + CODE_STEPLEFT +00C7: # 'Ç' + SKEY_C + KEY_BACK + KEY_COMA +00C8: # 'È' + SKEY_GRAVE + SKEY_E +00C9: # 'É' + KEY_ACUTE + SKEY_E +00CA: # 'Ê' + CODE_ALT + XKEY_CARET + SKEY_E +00CB: # 'Ë' + CODE_ALT + XKEY_UMLAUT + SKEY_E +00CC: # 'Ì' + SKEY_GRAVE + SKEY_I +00CD: # 'Í' + KEY_ACUTE + SKEY_I +00CE: # 'Î' + CODE_ALT + XKEY_CARET + SKEY_I +00CF: # 'Ï' + CODE_ALT + XKEY_UMLAUT + SKEY_I +00D0: # 'Ð' + KEY_MARGIN + CODE_STEPLEFT + KEY_MINUS + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_D +00D1: # 'Ñ' + SKEY_N + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +00D2: # 'Ò' + SKEY_GRAVE + SKEY_O +00D3: # 'Ó' + KEY_ACUTE + SKEY_O +00D4: # 'Ô' + CODE_ALT + XKEY_CARET + SKEY_O +00D5: # 'Õ' + SKEY_O + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +00D6: # 'Ö' + SKEY_OE +00D7: # '×' + KEY_X +00D8: # 'Ø' + SKEY_O + KEY_BACK + SKEY_SLASH +00D9: # 'Ù' + SKEY_GRAVE + SKEY_U +00DA: # 'Ú' + KEY_ACUTE + SKEY_U +00DB: # 'Û' + CODE_ALT + XKEY_CARET + SKEY_U +00DC: # 'Ü' + SKEY_UE +00DD: # 'Ý' + KEY_ACUTE + SKEY_Y +00DE: # 'Þ' + KEY_P + KEY_BACK + KEY_B +00DF: # 'ß' + KEY_SS +00E0: # 'à' + SKEY_GRAVE + KEY_A +00E1: # 'á' + KEY_ACUTE + KEY_A +00E2: # 'â' + CODE_ALT + XKEY_CARET + KEY_A +00E3: # 'ã' + KEY_A + KEY_BACK + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +00E4: # 'ä' + KEY_AE +00E5: # 'Ã¥' + KEY_A + KEY_BACK + CODE_ALT + XKEY_DEGREE +00E6: # 'æ' + KEY_MARGIN + CODE_STEPLEFT + KEY_A + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_E + CODE_STEPLEFT +00E7: # 'ç' + KEY_C + KEY_BACK + KEY_COMA +00E8: # 'è' + SKEY_GRAVE + KEY_E +00E9: # 'é' + KEY_ACUTE + KEY_E +00EA: # 'ê' + CODE_ALT + XKEY_CARET + KEY_E +00EB: # 'ë' + CODE_ALT + XKEY_UMLAUT + KEY_E +00EC: # 'ì' + SKEY_GRAVE + KEY_I +00ED: # 'í' + KEY_ACUTE + KEY_I +00EE: # 'î' + CODE_ALT + XKEY_CARET + KEY_I +00EF: # 'ï' + CODE_ALT + XKEY_UMLAUT + KEY_I +00F0: # 'ð' + KEY_D + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +00F1: # 'ñ' + KEY_N + KEY_BACK + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +00F2: # 'ò' + SKEY_GRAVE + KEY_O +00F3: # 'ó' + KEY_ACUTE + KEY_O +00F4: # 'ô' + CODE_ALT + XKEY_CARET + KEY_O +00F5: # 'õ' + KEY_O + KEY_BACK + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +00F6: # 'ö' + KEY_OE +00F7: # '÷' + SKEY_COLON + KEY_BACK + KEY_MINUS +00F8: # 'ø' + KEY_O + KEY_BACK + SKEY_SLASH +00F9: # 'ù' + SKEY_GRAVE + KEY_U +00FA: # 'ú' + KEY_ACUTE + KEY_U +00FB: # 'û' + CODE_ALT + XKEY_CARET + KEY_U +00FC: # 'ü' + KEY_UE +00FD: # 'ý' + KEY_ACUTE + KEY_Y +00FE: # 'þ' + KEY_P + KEY_BACK + KEY_B +00FF: # 'ÿ' + CODE_ALT + XKEY_UMLAUT + KEY_Y +0100: # 'Ā' + SKEY_A + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0101: # 'ā' + KEY_A + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0102: # 'Ă' + SKEY_GRAVE + SKEY_A + KEY_BACK + KEY_ACUTE + KEY_SPACE +0103: # 'ă' + SKEY_GRAVE + KEY_A + KEY_BACK + KEY_ACUTE + KEY_SPACE +0104: # 'Ą' + SKEY_A + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0105: # 'ą' + KEY_A + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0106: # 'Ć' + KEY_ACUTE + SKEY_C +0107: # 'ć' + KEY_ACUTE + KEY_C +0108: # 'Ĉ' + CODE_ALT + XKEY_CARET + SKEY_C +0109: # 'ĉ' + CODE_ALT + XKEY_CARET + KEY_C +010A: # 'Ċ' + SKEY_C + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +010B: # 'ċ' + KEY_C + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +010C: # 'Č' + SKEY_GRAVE + SKEY_C + KEY_BACK + KEY_ACUTE + KEY_SPACE +010D: # 'č' + SKEY_GRAVE + KEY_C + KEY_BACK + KEY_ACUTE + KEY_SPACE +010E: # 'Ď' + SKEY_GRAVE + SKEY_D + KEY_BACK + KEY_ACUTE + KEY_SPACE +010F: # 'ď' + SKEY_GRAVE + KEY_D + KEY_BACK + KEY_ACUTE + KEY_SPACE +0110: # 'Đ' + KEY_MARGIN + CODE_STEPLEFT + KEY_MINUS + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_D +0111: # 'đ' + KEY_D + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0112: # 'Ē' + SKEY_E + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0113: # 'ē' + KEY_E + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0114: # 'Ĕ' + SKEY_GRAVE + SKEY_E + KEY_BACK + KEY_ACUTE + KEY_SPACE +0115: # 'ĕ' + SKEY_GRAVE + KEY_E + KEY_BACK + KEY_ACUTE + KEY_SPACE +0116: # 'Ė' + SKEY_E + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0117: # 'ė' + KEY_E + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0118: # 'Ę' + SKEY_E + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0119: # 'ę' + KEY_E + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +011A: # 'Ě' + SKEY_GRAVE + SKEY_E + KEY_BACK + KEY_ACUTE + KEY_SPACE +011B: # 'ě' + SKEY_GRAVE + KEY_E + KEY_BACK + KEY_ACUTE + KEY_SPACE +011C: # 'Ĝ' + CODE_ALT + XKEY_CARET + SKEY_G +011D: # 'ĝ' + CODE_ALT + XKEY_CARET + KEY_G +011E: # 'Ğ' + SKEY_GRAVE + SKEY_G + KEY_BACK + KEY_ACUTE + KEY_SPACE +011F: # 'ğ' + SKEY_GRAVE + KEY_G + KEY_BACK + KEY_ACUTE + KEY_SPACE +0120: # 'Ä ' + SKEY_G + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0121: # 'Ä¡' + KEY_G + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0122: # 'Ä¢' + SKEY_G + KEY_BACK + KEY_COMA +0123: # 'Ä£' + KEY_G + KEY_BACK + KEY_COMA +0124: # 'Ĥ' + CODE_ALT + XKEY_CARET + SKEY_H +0125: # 'Ä¥' + CODE_ALT + XKEY_CARET + KEY_H +0126: # 'Ħ' + SKEY_H + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0127: # 'ħ' + KEY_H + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0128: # 'Ĩ' + SKEY_I + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0129: # 'Ä©' + KEY_I + KEY_BACK + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +012A: # 'Ī' + SKEY_I + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +012B: # 'Ä«' + KEY_I + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +012C: # 'Ĭ' + SKEY_GRAVE + SKEY_I + KEY_BACK + KEY_ACUTE + KEY_SPACE +012D: # 'Ä­' + SKEY_GRAVE + KEY_I + KEY_BACK + KEY_ACUTE + KEY_SPACE +012E: # 'Ä®' + SKEY_I + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +012F: # 'į' + KEY_I + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0130: # 'Ä°' + SKEY_I + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0131: # 'ı' + KEY_I +0132: # 'IJ' + KEY_MARGIN + CODE_STEPLEFT + SKEY_I + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_J + CODE_STEPLEFT +0133: # 'ij' + KEY_MARGIN + CODE_STEPLEFT + KEY_I + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_J + CODE_STEPLEFT +0134: # 'Ä´' + CODE_ALT + XKEY_CARET + SKEY_J +0135: # 'ĵ' + CODE_ALT + XKEY_CARET + KEY_J +0136: # 'Ķ' + SKEY_K + KEY_BACK + KEY_COMA +0137: # 'Ä·' + KEY_K + KEY_BACK + KEY_COMA +0138: # 'ĸ' + SKEY_K +0139: # 'Ĺ' + KEY_ACUTE + SKEY_L +013A: # 'ĺ' + KEY_ACUTE + KEY_L +013B: # 'Ä»' + SKEY_L + KEY_BACK + KEY_COMA +013C: # 'ļ' + KEY_L + KEY_BACK + KEY_COMA +013D: # 'Ľ' + SKEY_L + KEY_BACK + CODE_HALFUP + KEY_COMA + CODE_HALFDOWN +013E: # 'ľ' + KEY_L + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + CODE_HALFUP + KEY_MARGIN + KEY_COMA + CODE_HALFDOWN + CODE_STEPLEFT +013F: # 'Ä¿' + SKEY_L + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0140: # 'ŀ' + KEY_L + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + CODE_HALFUP + KEY_MARGIN + KEY_DOT + CODE_HALFDOWN + CODE_STEPLEFT +0141: # 'Ł' + SKEY_L + KEY_BACK + KEY_MINUS +0142: # 'ł' + KEY_L + KEY_BACK + KEY_MINUS +0143: # 'Ń' + KEY_ACUTE + SKEY_N +0144: # 'ń' + KEY_ACUTE + KEY_N +0145: # 'Ņ' + SKEY_N + KEY_BACK + KEY_COMA +0146: # 'ņ' + KEY_N + KEY_BACK + KEY_COMA +0147: # 'Ň' + SKEY_GRAVE + SKEY_N + KEY_BACK + KEY_ACUTE + KEY_SPACE +0148: # 'ň' + SKEY_GRAVE + KEY_N + KEY_BACK + KEY_ACUTE + KEY_SPACE +014A: # 'Ŋ' + SKEY_N + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +014B: # 'ŋ' + KEY_N + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +014C: # 'Ō' + SKEY_O + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +014D: # 'ō' + KEY_O + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +014E: # 'Ŏ' + SKEY_GRAVE + SKEY_O + KEY_BACK + KEY_ACUTE + KEY_SPACE +014F: # 'ŏ' + SKEY_GRAVE + KEY_O + KEY_BACK + KEY_ACUTE + KEY_SPACE +0150: # 'Ő' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + KEY_BACK + SKEY_O +0151: # 'ő' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + KEY_BACK + KEY_O +0152: # 'Œ' + KEY_MARGIN + CODE_STEPLEFT + SKEY_O + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + SKEY_E + CODE_STEPLEFT +0153: # 'œ' + KEY_MARGIN + CODE_STEPLEFT + KEY_O + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_E + CODE_STEPLEFT +0154: # 'Ŕ' + KEY_ACUTE + SKEY_R +0155: # 'ŕ' + KEY_ACUTE + KEY_R +0156: # 'Ŗ' + SKEY_R + KEY_BACK + KEY_COMA +0157: # 'ŗ' + KEY_R + KEY_BACK + KEY_COMA +0158: # 'Ř' + SKEY_GRAVE + SKEY_R + KEY_BACK + KEY_ACUTE + KEY_SPACE +0159: # 'ř' + SKEY_GRAVE + KEY_R + KEY_BACK + KEY_ACUTE + KEY_SPACE +015A: # 'Ś' + KEY_ACUTE + SKEY_S +015B: # 'ś' + KEY_ACUTE + KEY_S +015C: # 'Ŝ' + CODE_ALT + XKEY_CARET + SKEY_S +015D: # 'ŝ' + CODE_ALT + XKEY_CARET + KEY_S +015E: # 'Ş' + SKEY_S + KEY_BACK + KEY_COMA +015F: # 'ş' + KEY_S + KEY_BACK + KEY_COMA +0160: # 'Å ' + SKEY_GRAVE + SKEY_S + KEY_BACK + KEY_ACUTE + KEY_SPACE +0161: # 'Å¡' + SKEY_GRAVE + KEY_S + KEY_BACK + KEY_ACUTE + KEY_SPACE +0162: # 'Å¢' + SKEY_T + KEY_BACK + KEY_COMA +0163: # 'Å£' + KEY_T + KEY_BACK + KEY_COMA +0164: # 'Ť' + SKEY_GRAVE + SKEY_T + KEY_BACK + KEY_ACUTE + KEY_SPACE +0165: # 'Å¥' + KEY_T + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + CODE_HALFUP + KEY_MARGIN + KEY_COMA + CODE_HALFDOWN + CODE_STEPLEFT +0166: # 'Ŧ' + SKEY_T + KEY_BACK + KEY_MINUS +0167: # 'ŧ' + KEY_T + KEY_BACK + KEY_MINUS +0168: # 'Ũ' + SKEY_U + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +0169: # 'Å©' + KEY_U + KEY_BACK + CODE_ALT + XKEY_CARET + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +016A: # 'Ū' + SKEY_U + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +016B: # 'Å«' + KEY_U + KEY_BACK + CODE_HALFUP + KEY_MINUS + CODE_HALFDOWN +016C: # 'Ŭ' + SKEY_GRAVE + SKEY_U + KEY_BACK + KEY_ACUTE + KEY_SPACE +016D: # 'Å­' + SKEY_GRAVE + KEY_U + KEY_BACK + KEY_ACUTE + KEY_SPACE +016E: # 'Å®' + SKEY_U + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +016F: # 'ů' + KEY_U + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +0170: # 'Å°' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + KEY_BACK + SKEY_U +0171: # 'ű' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + KEY_BACK + KEY_U +0172: # 'Ų' + SKEY_U + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0173: # 'ų' + KEY_U + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +0174: # 'Å´' + CODE_ALT + XKEY_CARET + SKEY_W +0175: # 'ŵ' + CODE_ALT + XKEY_CARET + KEY_W +0176: # 'Ŷ' + CODE_ALT + XKEY_CARET + SKEY_Y +0177: # 'Å·' + CODE_ALT + XKEY_CARET + KEY_Y +0178: # 'Ÿ' + CODE_ALT + XKEY_UMLAUT + SKEY_Y +0179: # 'Ź' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_Z +017A: # 'ź' + KEY_ACUTE + KEY_Z +017B: # 'Å»' + SKEY_Z + KEY_BACK + KEY_MINUS +017C: # 'ż' + KEY_Z + KEY_BACK + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +017D: # 'Ž' + SKEY_GRAVE + SKEY_Z + KEY_BACK + KEY_ACUTE + KEY_SPACE +017E: # 'ž' + SKEY_GRAVE + KEY_Z + KEY_BACK + KEY_ACUTE + KEY_SPACE +0218: # 'Ș' +0219: # 'ș' +021A: # 'Ț' +021B: # 'ț' +02C7: # 'ˇ' + SKEY_GRAVE + KEY_SPACE + KEY_BACK + KEY_ACUTE + KEY_SPACE +02D8: # '˘' + SKEY_GRAVE + KEY_SPACE + KEY_BACK + KEY_ACUTE + KEY_SPACE +02D9: # '˙' + CODE_HALFUP + KEY_DOT + CODE_HALFDOWN +02DB: # '˛' + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_COMA + CODE_STEPLEFT +02DD: # '˝' + KEY_MARGIN + CODE_STEPLEFT + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + KEY_ACUTE + KEY_SPACE + CODE_STEPLEFT +2013: # '–' +2014: # '—' +2015: # '―' +2018: # '‘' +2019: # '’' +201A: # '‚' +201C: # '“' +201D: # '”' +201E: # '„' +2020: # '†' +2021: # '‡' +2022: # '•' +2026: # '…' +2030: # '‰' +2039: # '‹' +203A: # '›' +20AC: # '€' +2122: # '™' +2500: # '─' +2502: # '│' +250C: # '┌' +2510: # '┐' +2514: # '└' +2518: # '┘' +251C: # '├' +2524: # '┤' +252C: # '┬' +2534: # '┴' +253C: # '┼' +2550: # '═' +2551: # '║' +2554: # '╔' +2557: # '╗' +255A: # '╚' +255D: # '╝' +2560: # '╠' +2563: # '╣' +2566: # '╦' +2569: # '╩' +256C: # '╬' +2580: # '▀' +2584: # '▄' +2588: # '█' +2591: # '░' +2592: # '▒' +2593: # '▓' +25A0: # '■' +FFFD: # '�' + KEY_MARGIN + CODE_STEPLEFT + CODE_ALT + XKEY_LT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + SKEY_QUEST + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT + CODE_STEPLEFT_EXTRA + KEY_MARGIN + CODE_ALT + XKEY_GT + CODE_STEPLEFT + +TKEY_AT: + 0040 # '@' +TKEY_TILDE: + 007E # '~' +TCODE_ESC: + 001B +KEY_1: + 0031 # '1' +SKEY_EXCL: + 0021 # '!' +TCODE_LT: + 003C # '<' +TCODE_LT_: + 003C # '<' +KEY_2: + 0032 # '2' +SKEY_QUOT: + 0022 # '"' +TCODE_GT: + 003E # '>' +TCODE_GT_: + 003E # '>' +KEY_3: + 0033 # '3' +SKEY_PARAG: + 00A7 # '§' +TCODE_QUOT: + 0027 # ''' +TCODE_QUOT_: + 0027 # ''' +KEY_4: + 0034 # '4' +SKEY_PLUS: + 002B # '+' +KEY_5: + 0035 # '5' +SKEY_PERCENT: + 0025 # '%' +KEY_6: + 0036 # '6' +SKEY_AMP: + 0026 # '&' +KEY_7: + 0037 # '7' +SKEY_SLASH: + 002F # '/' +KEY_8: + 0038 # '8' +SKEY_LPAREN: + 0028 # '(' +KEY_9: + 0039 # '9' +SKEY_RPAREN: + 0029 # ')' +KEY_0: + 0030 # '0' +SKEY_EQ: + 003D # '=' +TCODE_HASH: + 0023 # '#' +TCODE_DOLLAR: + 0024 # '$' +KEY_SS: + 00DF # 'ß' +SKEY_QUEST: + 003F # '?' +TCODE_POUND: + 00A3 # '£' +TCODE_DEGREE: + 00B0 # '°' +KEY_ACUTE: + 00B4 # '´' +SKEY_GRAVE: + 0060 # '`' +TCODE_DASH: + 005E # '^' +TCODE_UMLAUT: + 00A8 # '¨' +KEY_BACK: + 0008 +KEY_TAB: + 0009 +KEY_Q: + 0071 # 'q' +SKEY_Q: + 0051 # 'Q' +KEY_W: + 0077 # 'w' +SKEY_W: + 0057 # 'W' +KEY_E: + 0065 # 'e' +SKEY_E: + 0045 # 'E' +TCODE_E: + 0119 # 'ę' +TCODE_E_: + 0118 # 'Ę' +KEY_R: + 0072 # 'r' +SKEY_R: + 0052 # 'R' +KEY_T: + 0074 # 't' +SKEY_T: + 0054 # 'T' +KEY_Z: + 007A # 'z' +SKEY_Z: + 005A # 'Z' +TCODE_Z: + 017C # 'ż' +TCODE_Z_: + 017B # 'Å»' +KEY_U: + 0075 # 'u' +SKEY_U: + 0055 # 'U' +KEY_I: + 0069 # 'i' +SKEY_I: + 0049 # 'I' +KEY_O: + 006F # 'o' +SKEY_O: + 004F # 'O' +TCODE_O: + 00F3 # 'ó' +TCODE_O_: + 00D3 # 'Ó' +KEY_P: + 0070 # 'p' +SKEY_P: + 0050 # 'P' +KEY_UE: + 00FC # 'ü' +SKEY_UE: + 00DC # 'Ü' +TCODE_BSLASH: + 005C # '\' +TCODE_WALL: + 007C # '|' +KEY_RETURN: + 000D +SKEY_RETURN: + 000D +KEY_A: + 0061 # 'a' +SKEY_A: + 0041 # 'A' +TCODE_A: + 0105 # 'ą' +TCODE_A_: + 0104 # 'Ą' +KEY_S: + 0073 # 's' +SKEY_S: + 0053 # 'S' +TCODE_S: + 015B # 'ś' +TCODE_S_: + 015A # 'Ś' +KEY_D: + 0064 # 'd' +SKEY_D: + 0044 # 'D' +TCODE_D: + 015B # 'ś' +TCODE_D_: + 015A # 'Ś' +KEY_F: + 0066 # 'f' +SKEY_F: + 0046 # 'F' +KEY_G: + 0067 # 'g' +SKEY_G: + 0047 # 'G' +KEY_H: + 0068 # 'h' +SKEY_H: + 0048 # 'H' +KEY_J: + 006A # 'j' +SKEY_J: + 004A # 'J' +KEY_K: + 006B # 'k' +SKEY_K: + 004B # 'K' +KEY_L: + 006C # 'l' +SKEY_L: + 004C # 'L' +TCODE_L: + 0142 # 'ł' +TCODE_L_: + 0141 # 'Ł' +KEY_OE: + 00F6 # 'ö' +SKEY_OE: + 00D6 # 'Ö' +TCODE_LSQBR: + 005B # '[' +TCODE_LCURL: + 007B # '{' +KEY_AE: + 00E4 # 'ä' +SKEY_AE: + 00C4 # 'Ä' +TCODE_RSQBR: + 005D # ']' +TCODE_RCURL: + 007D # '}' +KEY_Y: + 0079 # 'y' +SKEY_Y: + 0059 # 'Y' +TCODE_Y: + 017A # 'ź' +TCODE_Y_: + 0179 # 'Ź' +KEY_X: + 0078 # 'x' +SKEY_X: + 0058 # 'X' +KEY_C: + 0063 # 'c' +SKEY_C: + 0043 # 'C' +TCODE_C: + 0107 # 'ć' +TCODE_C_: + 0106 # 'Ć' +KEY_V: + 0076 # 'v' +SKEY_V: + 0056 # 'V' +KEY_B: + 0062 # 'b' +SKEY_B: + 0042 # 'B' +KEY_N: + 006E # 'n' +SKEY_N: + 004E # 'N' +TCODE_N: + 0144 # 'ń' +TCODE_N_: + 0143 # 'Ń' +KEY_M: + 006D # 'm' +SKEY_M: + 004D # 'M' +KEY_COMA: + 002C # ',' +SKEY_SEMI: + 003B # ';' +KEY_DOT: + 002E # '.' +SKEY_COLON: + 003A # ':' +KEY_MINUS: + 002D # '-' +SKEY_UNDER: + 005F # '_' +TCODE_STAR: + 002A # '*' +KEY_SPACE: + 0020 # ' ' +SKEY_SPACE: + 0020 # ' ' +KEY_ERASE1: + 007F +KEY_ERASEW: + 007F diff --git a/keyboard.h b/keyboard.h new file mode 100644 index 0000000..6760d5f --- /dev/null +++ b/keyboard.h @@ -0,0 +1,355 @@ +/* +Actual kezboard layout +all numbers in octal + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +|mar|! <|" >|§ '| + | % | & | / | ( | ) |= $|? °|` ¨|bac| +|gin|1 |2 |3 | 4 | 5 | 6 | 7 | 8 | 9 |0 #|ß £|´ ^|ksp| ++---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | | | | | | | | | | | | | +| tab | Q | W | E | R | T | Z | U | I | O | P | Ü | ret | ++-+---++--++--++--++--++--++--++--++--++--++--++--++urn | +| |caps| | | | | | | | | | | | | +| |lock| A | S | D | F | G | H | J | K | L | Ö | Ä | | ++-+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+----+ +| | | | | | | | | ; | : |_ | | +| shift | Y | X | C | V | B | N | M | , | . |- *| shift| ++--------+---+---+---+---+---+---+---+---+---+---+------+ + |co | | | | + |de | space | | ) | ( | =$ | §' | / | + | +00| 1 | 2 | 9 | 8 | 0# | 3 | 7 | 4 | +--+----+----+----+----+----+----+----+----+ + |mar | | `¨ | | ?° | | & | % | +10|gin | | ´^ | | ߣ | | 6 | 5 | +--+----+----+----+----+----+----+----+----+ + | | |back| | | | | | +20| Q | W |spac| i | Ü | E | U | R | +--+----+----+----+----+----+----+----+----+ + | | | | | | re | | | +30|tab | | | | P |turn| Z | T | +--+----+----+----+----+----+----+----+----+ + | | | | | | | | | +40| A | S | L | K | Ö | D | J | F | +--+----+----+----+----+----+----+----+----+ + |caps| co | | shi| | | | | +50|lock| de | O | ft | Ä | | N | B | +--+----+----+----+----+----+----+----+----+ + | | | : | ; | _ | | | | +60| Y | X | . | , | -* | C | M | V | +--+----+----+----+----+----+----+----+----+ + | spa| | | | | | | | +70| ce | | ALLOW CROSSING MARGIN +72 SET LEFT MARGIN +00 1 SET RIGHT MARGIN +01 2 SET TAB STOP +05 3 CLEAR TAB STOP +07 4 6 LPI +17 5 4 LPI +16 6 3 LPI +06 7 10 CPI +03 8 12 CPI +02 9 STEP DOWN +04 0 STEP UP +22 |<- STEP LEFT +20 Q RETURN TO LEFT MARGIN +27 R AUTORETURN +26 U UNDERLINE +23 I INDEX +35 ret CLEAR INDEX +45 D CLEAR ALL TAB STOPS +43 K WEAK STRIKE +42 L STRONG STRIKE +60 Y ALTERNATIVE SYMBOL +65 C CENTER +57 B BOLD +72 |§ '|+ |% |& |/ |( |) |= $|? °|` ¨|bac| +|@\e|1 <|2 >|3 '|4 |5 |6 |7 |8 |9 |0 #|ß £|´ ^|ksp| ++---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| |Q |W |E Ę|R |T |Z Å»|U |I |O Ó|P |Ü || | +| tab |q |w |e ę|r |t |z ż|u |i |o ó|p |ü \| ret | ++-+---++--++--++--++--++--++--++--++--++--++--++--++urn | +| |next|A Ą|S |D Ś|F |G |H |J |K |L Ł|Ö {|Ä }| | +| |page|a ą|s ś|d |f |g |h |j |k |l ł|ö [|ä ]| | ++-+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+----+ +| |Y Ź|X |C Ć|V |B |N Ń|M |; |: |_ | | +| shift |y ź|x |c ć|v |b |n ń|m |, |. |- *| shift| ++--------+---+---+---+---+---+---+---+---+---+---+------+ + |co | |con| | + |de | space |trl|del| + +---+---------------------------+---+---+ +*/ + +#define KEYB_ROW 070 +#define KEYB_COL 007 + +#define KEYB_ROW_0 000 +#define KEYB_ROW_1 010 +#define KEYB_ROW_2 020 +#define KEYB_ROW_3 030 +#define KEYB_ROW_4 040 +#define KEYB_ROW_5 050 +#define KEYB_ROW_6 060 +#define KEYB_ROW_7 070 + +#define KEYB_COL_0 000 +#define KEYB_COL_1 001 +#define KEYB_COL_2 002 +#define KEYB_COL_3 003 +#define KEYB_COL_4 004 +#define KEYB_COL_5 005 +#define KEYB_COL_6 006 +#define KEYB_COL_7 007 + +#define KEYB_0 0b00000001 +#define KEYB_1 0b00000010 +#define KEYB_2 0b00000100 +#define KEYB_3 0b00001000 +#define KEYB_4 0b00010000 +#define KEYB_5 0b00100000 +#define KEYB_6 0b01000000 +#define KEYB_7 0b10000000 + +#define KEYB_SHIFT 0100 +#define KEYB_CODE 0200 + +#define KEYB_MOD_IND 5 +#define KEYB_SHIFT_BIT 0b00001000 +#define KEYB_CODE_BIT 0b00000010 + + +#define KEY_MARGIN 010 +#define KEY_1 000 +#define KEY_2 001 +#define KEY_3 005 +#define KEY_4 007 +#define KEY_5 017 +#define KEY_6 016 +#define KEY_7 006 +#define KEY_8 003 +#define KEY_9 002 +#define KEY_0 004 +#define KEY_SS 014 +#define KEY_ACUTE 012 +#define KEY_BACK 022 + +#define KEY_TAB 030 +#define KEY_Q 020 +#define KEY_W 021 +#define KEY_E 025 +#define KEY_R 027 +#define KEY_T 037 +#define KEY_Z 036 +#define KEY_U 026 +#define KEY_I 023 +#define KEY_O 052 +#define KEY_P 034 +#define KEY_UE 024 + +#define KEY_RETURN 035 + +#define KEY_CAPS 050 +#define KEY_A 040 +#define KEY_S 041 +#define KEY_D 045 +#define KEY_F 047 +#define KEY_G 077 +#define KEY_H 076 +#define KEY_J 046 +#define KEY_K 043 +#define KEY_L 042 +#define KEY_OE 044 +#define KEY_AE 054 + +#define KEY_SHIFT 053 +#define KEY_Y 060 +#define KEY_X 061 +#define KEY_C 065 +#define KEY_V 067 +#define KEY_B 057 +#define KEY_N 056 +#define KEY_M 066 +#define KEY_COMA 063 +#define KEY_DOT 062 +#define KEY_MINUS 064 + +#define KEY_CODE 051 +#define KEY_SPACE 070 +#define KEY_ERASEW 072 +#define KEY_ERASE1 074 + + +#define SKEY_EXCL (KEY_1 | KEYB_SHIFT) +#define SKEY_QUOT (KEY_2 | KEYB_SHIFT) +#define SKEY_PARAG (KEY_3 | KEYB_SHIFT) +#define SKEY_PLUS (KEY_4 | KEYB_SHIFT) +#define SKEY_PERCENT (KEY_5 | KEYB_SHIFT) +#define SKEY_AMP (KEY_6 | KEYB_SHIFT) +#define SKEY_SLASH (KEY_7 | KEYB_SHIFT) +#define SKEY_LPAREN (KEY_8 | KEYB_SHIFT) +#define SKEY_RPAREN (KEY_9 | KEYB_SHIFT) +#define SKEY_EQ (KEY_0 | KEYB_SHIFT) +#define SKEY_QUEST (KEY_SS | KEYB_SHIFT) +#define SKEY_GRAVE (KEY_ACUTE| KEYB_SHIFT) + +#define SKEY_Q (KEY_Q | KEYB_SHIFT) +#define SKEY_W (KEY_W | KEYB_SHIFT) +#define SKEY_E (KEY_E | KEYB_SHIFT) +#define SKEY_R (KEY_R | KEYB_SHIFT) +#define SKEY_T (KEY_T | KEYB_SHIFT) +#define SKEY_Z (KEY_Z | KEYB_SHIFT) +#define SKEY_U (KEY_U | KEYB_SHIFT) +#define SKEY_I (KEY_I | KEYB_SHIFT) +#define SKEY_O (KEY_O | KEYB_SHIFT) +#define SKEY_P (KEY_P | KEYB_SHIFT) +#define SKEY_UE (KEY_UE | KEYB_SHIFT) + +#define SKEY_RETURN (KEY_RETURN|KEYB_SHIFT) + +#define SKEY_CAPS (KEY_CAPS | KEYB_SHIFT) +#define SKEY_A (KEY_A | KEYB_SHIFT) +#define SKEY_S (KEY_S | KEYB_SHIFT) +#define SKEY_D (KEY_D | KEYB_SHIFT) +#define SKEY_F (KEY_F | KEYB_SHIFT) +#define SKEY_G (KEY_G | KEYB_SHIFT) +#define SKEY_H (KEY_H | KEYB_SHIFT) +#define SKEY_J (KEY_J | KEYB_SHIFT) +#define SKEY_K (KEY_K | KEYB_SHIFT) +#define SKEY_L (KEY_L | KEYB_SHIFT) +#define SKEY_OE (KEY_OE | KEYB_SHIFT) +#define SKEY_AE (KEY_AE | KEYB_SHIFT) + +#define SKEY_Y (KEY_Y | KEYB_SHIFT) +#define SKEY_X (KEY_X | KEYB_SHIFT) +#define SKEY_C (KEY_C | KEYB_SHIFT) +#define SKEY_V (KEY_V | KEYB_SHIFT) +#define SKEY_B (KEY_B | KEYB_SHIFT) +#define SKEY_N (KEY_N | KEYB_SHIFT) +#define SKEY_M (KEY_M | KEYB_SHIFT) +#define SKEY_SEMI (KEY_COMA | KEYB_SHIFT) +#define SKEY_COLON (KEY_DOT | KEYB_SHIFT) +#define SKEY_UNDER (KEY_MINUS| KEYB_SHIFT) + +#define SKEY_SPACE (KEY_SPACE| KEYB_SHIFT) + +#define XKEY_LT (KEY_1 | KEYB_SHIFT) +#define XKEY_GT (KEY_2 | KEYB_SHIFT) +#define XKEY_QUOT (KEY_3 | KEYB_SHIFT) +#define XKEY_HASH (KEY_0 ) +#define XKEY_DOLLAR (KEY_0 | KEYB_SHIFT) +#define XKEY_POUND (KEY_SS ) +#define XKEY_DEGREE (KEY_SS | KEYB_SHIFT) +#define XKEY_CARET (KEY_ACUTE ) +#define XKEY_UMLAUT (KEY_ACUTE| KEYB_SHIFT) +#define XKEY_STAR (KEY_MINUS ) + + +#define CODE_LMARGIN (KEYB_CODE | KEY_MARGIN) +#define CODE_RMARGIN (KEYB_CODE | KEY_1 ) +#define CODE_TABPLUS (KEYB_CODE | KEY_2 ) +#define CODE_TABMINUS (KEYB_CODE | KEY_3 ) +#define CODE_LINE1 (KEYB_CODE | KEY_4 ) +#define CODE_LINE1_5 (KEYB_CODE | KEY_5 ) +#define CODE_LINE2 (KEYB_CODE | KEY_6 ) +#define CODE_PITCH10 (KEYB_CODE | KEY_7 ) +#define CODE_PITCH12 (KEYB_CODE | KEY_8 ) +#define CODE_HALFDOWN (KEYB_CODE | KEY_9 ) +#define CODE_HALFUP (KEYB_CODE | KEY_0 ) +#define CODE_STEPLEFT (KEYB_CODE | KEY_BACK ) +#define CODE_TABBACK (KEYB_CODE | KEY_TAB ) +#define CODE_RETURN (KEYB_CODE | KEY_Q ) +#define CODE_AUTORETURN (KEYB_CODE | KEY_R ) +#define CODE_UNDER (KEYB_CODE | KEY_U ) +#define CODE_IND (KEYB_CODE | KEY_I ) +#define CODE_NOTAB (KEYB_CODE | KEY_D ) +#define CODE_WEAK (KEYB_CODE | KEY_K ) +#define CODE_STRONG (KEYB_CODE | KEY_L ) +#define CODE_ALT (KEYB_CODE | KEY_Y ) +#define CODE_CENTER (KEYB_CODE | KEY_C ) +#define CODE_BOLD (KEYB_CODE | KEY_B ) + +#define CODE_BELL (KEYB_CODE | KEY_ACUTE ) +#define CODE_STEPLEFT_EXTRA (CODE_STEPLEFT | KEYB_SHIFT) + +#define TKEY_AT KEY_MARGIN +#define TKEY_TILDE (KEY_MARGIN | KEYB_SHIFT) + +#define TCODE_ESC (KEYB_CODE | KEY_MARGIN ) +#define TCODE_LT (KEYB_CODE | KEY_1 ) +#define TCODE_LT_ (KEYB_SHIFT| TCODE_LT ) +#define TCODE_GT (KEYB_CODE | KEY_2 ) +#define TCODE_GT_ (KEYB_SHIFT| TCODE_GT ) +#define TCODE_QUOT (KEYB_CODE | KEY_3 ) +#define TCODE_QUOT_ (KEYB_SHIFT| TCODE_QUOT ) +#define TCODE_HASH (KEYB_CODE | KEY_0 ) +#define TCODE_DOLLAR (KEYB_SHIFT| TCODE_HASH ) +#define TCODE_POUND (KEYB_CODE | KEY_SS ) +#define TCODE_DEGREE (KEYB_SHIFT| TCODE_POUND ) +#define TCODE_DASH (KEYB_CODE | KEY_ACUTE ) +#define TCODE_UMLAUT (KEYB_SHIFT| TCODE_DASH ) +#define TCODE_E (KEYB_CODE | KEY_E ) +#define TCODE_E_ (KEYB_SHIFT| TCODE_E ) +#define TCODE_Z (KEYB_CODE | KEY_Z ) +#define TCODE_Z_ (KEYB_SHIFT| TCODE_Z ) +#define TCODE_O (KEYB_CODE | KEY_O ) +#define TCODE_O_ (KEYB_SHIFT| TCODE_O ) +#define TCODE_BSLASH (KEYB_CODE | KEY_UE ) +#define TCODE_WALL (KEYB_SHIFT| TCODE_BSLASH) +#define TCODE_A (KEYB_CODE | KEY_A ) +#define TCODE_A_ (KEYB_SHIFT| TCODE_A ) +#define TCODE_S (KEYB_CODE | KEY_S ) +#define TCODE_S_ (KEYB_SHIFT| TCODE_S ) +#define TCODE_D (KEYB_CODE | KEY_D ) +#define TCODE_D_ (KEYB_SHIFT| TCODE_D ) +#define TCODE_L (KEYB_CODE | KEY_L ) +#define TCODE_L_ (KEYB_SHIFT| TCODE_L ) +#define TCODE_LSQBR (KEYB_CODE | KEY_OE ) +#define TCODE_LCURL (KEYB_SHIFT| TCODE_LSQBR ) +#define TCODE_RSQBR (KEYB_CODE | KEY_AE ) +#define TCODE_RCURL (KEYB_SHIFT| TCODE_RSQBR ) +#define TCODE_Y (KEYB_CODE | KEY_Y ) +#define TCODE_Y_ (KEYB_SHIFT| TCODE_Y ) +#define TCODE_X (KEYB_CODE | KEY_X ) +#define TCODE_X_ (KEYB_SHIFT| TCODE_X ) +#define TCODE_C (KEYB_CODE | KEY_C ) +#define TCODE_C_ (KEYB_SHIFT| TCODE_C ) +#define TCODE_N (KEYB_CODE | KEY_N ) +#define TCODE_N_ (KEYB_SHIFT| TCODE_N ) +#define TCODE_STAR (KEYB_CODE | KEY_MINUS ) diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..6988639 --- /dev/null +++ b/license.txt @@ -0,0 +1,5 @@ +This my software is released under the 2-clause BSD license. + +It includes the makefile (copied from WinAVR) which is in the public domain. + +TODO: include license information in all relevant files. diff --git a/maszyna.c b/maszyna.c new file mode 100644 index 0000000..d8857cc --- /dev/null +++ b/maszyna.c @@ -0,0 +1,6072 @@ +/* +Copyright 2022 Balthasar Szczepański + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. 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. + +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 HOLDER 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 +#include +#include +#include +#include + +#include "keyboard.h" +#include "keyboard-patterns.h" + + +// hex mode command + +#define HEX_NOTHING 0b00000000 +#define HEX_AVAILABLE 0b00000001 +#define HEX_FORCE 0b00000010 +#define HEX_RESET 0b00000100 +#define HEX_FINISH 0b00001000 + +// menu buttons + +#define MENU_NONE 0355 // choose something not present on kezboard +#define MENU_ENTER (KEY_ERASEW | KEYB_CODE) +#define MENU_OUTPUT KEY_ERASEW +#define MENU_EXIT KEY_MARGIN +#define MENU_CONFIRM KEY_RETURN +#define MENU_BAUD KEY_1 +#define MENU_BITS KEY_2 +#define MENU_FLOW KEY_3 +#define MENU_ECHO KEY_4 +#define MENU_NEWLINE KEY_5 +#define MENU_DELETE KEY_6 +#define MENU_REPLACE KEY_7 +#define MENU_ENCODING KEY_8 +#define MENU_PWIDTH KEY_Q +#define MENU_LMARGIN KEY_W +#define MENU_RMARGIN KEY_E +#define MENU_TWIDTH KEY_R +#define MENU_PHEIGHT KEY_T +#define MENU_TMARGIN KEY_Z +#define MENU_BMARGIN KEY_U +#define MENU_THEIGHT KEY_I +#define MENU_HTAB KEY_O +#define MENU_VTAB KEY_P +#define MENU_CWIDTH KEY_A +#define MENU_LHEIGHT KEY_S +#define MENU_PAPER KEY_D + +#define QMENU_PAGE KEY_CAPS +#define QMENU_FPAGE SKEY_CAPS +#define QMENU_BOLD CODE_BOLD +#define QMENU_UNDER CODE_UNDER +#define QMENU_UNDER2 (CODE_UNDER | KEYB_SHIFT) +#define QMENU_CROSS (KEY_P | KEYB_CODE) +#define QMENU_OVER (KEY_P | KEYB_CODE | KEYB_SHIFT) +#define QMENU_WEAK CODE_WEAK +#define QMENU_STRONG (CODE_WEAK | KEYB_SHIFT) +#define QMENU_6LPI CODE_LINE1 +#define QMENU_4LPI CODE_LINE1_5 +#define QMENU_3LPI CODE_LINE2 +#define QMENU_10CPI CODE_PITCH10 +#define QMENU_12CPI CODE_PITCH12 +#define QMENU_ECHO CODE_AUTORETURN +#define QMENU_PAPER (KEY_RETURN | KEYB_CODE) +#define QMENU_EXIT (KEY_MARGIN | KEYB_CODE | KEYB_SHIFT) +#define QMENU_HEX (KEY_TAB | KEYB_CODE) + +// menu text + +#define TEXT_MENU_LIST ((uint8_t *) \ + "MENU\r\n" \ + "1:baud 2:bits 3:flowctrl 4:echo 5:CR/LF 6:BS/DEL 7:replace 8:encoding\r\n" \ + "Q:width W:left E:right R:Twidth T:height Z:top U:bottom I:Theight\r\n" \ + "O:Htab P: Vtab A:Cwidth S:Lheight D:paper DEL: help ESC: exit\r\n> ") +#define TEXT_MENU_EXIT ((uint8_t *) \ + "EXIT\r\n") +#define TEXT_MENU_BAUD ((uint8_t *) \ + "SET BAUD RATE\r\n" \ + "134,150,200,300,600,1200,1800,2400,4800,7200,9600,14400,\r\n" \ + "19200,28800,31520,57600,76800,115200,125000,250000,\r\n" \ + "> ") +#define TEXT_MENU_BITS ((uint8_t *) \ + "SET SERIAL MODE\r\n" \ + "1:8n1 2:8e1 3:8o1 4:8n2 5:8e2 6:8o2\r\n" \ + "7:7n1 8:7e1 9:7o1 10:7n2 11:7e2 12:7o2\r\n" \ + "> ") +#define TEXT_MENU_FLOW ((uint8_t *) \ + "SET FLOW CONTROPL\r\n" \ + "HW: 1:FD(RTR/CTS) 2:HD,DTE(RTS/CTS) 3:HD,DCE(CTS/RTS) 4:none\r\n" \ + "SW: 5:XON/XOFF 6:none\r\n> ") +#define TEXT_MENU_NEWLINE ((uint8_t *) \ + "SET NEWLINE HANDLING\r\n" \ + "RECEIVE: 1:CR->CRLF 2:LF->CRLF 3:any->CRLF 4:no change\r\n" \ + "SEND: 5:CR 6:LF 7:CRLF\r\n> ") +#define TEXT_MENU_ECHO ((uint8_t *) \ + "SET LOCAL ECHO\r\n" \ + "1:ON 2:OFF\r\n> ") +#define TEXT_MENU_DELETE ((uint8_t *) \ + "SET BACKSPACE/DELETE KEY CODE\r\n" \ + "1:BS=08 2:BS=7F 3:DEL=7F 4:DEL=08\r\n> ") +#define TEXT_MENU_REPLACE ((uint8_t *) \ + "SET UNKNOWN CHARACTER HANDLING\r\n" \ + "1: 2:? 3:_ 4:SPACE 5:ignore\r\n> ") +#define TEXT_MENU_ENCODING ((uint8_t *) \ + "SET CHARACTER ENCODING\r\n" \ + "1,2,3,4,9,10,13,15,16:ISO8859 1250,852:codepage 8:UTF-8\r\n> ") +#define TEXT_MENU_PWIDTH ((uint8_t *) \ + "SET PAGE WIDTH (in columns)\r\n> ") +#define TEXT_MENU_LMARGIN ((uint8_t *) \ + "SET LEFT MARGIN (in columns)\r\n> ") +#define TEXT_MENU_RMARGIN ((uint8_t *) \ + "SET RIGHT MARGIN (in columns)\r\n> ") +#define TEXT_MENU_TWIDTH ((uint8_t *) \ + "SET TEXT WIDTH (in columns)\r\n> ") +#define TEXT_MENU_PHEIGHT ((uint8_t *) \ + "SET PAGE HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_TMARGIN ((uint8_t *) \ + "SET TOP MARGIN (in lines)\r\n> ") +#define TEXT_MENU_BMARGIN ((uint8_t *) \ + "SET BOTTOM MARGIN (in lines)\r\n> ") +#define TEXT_MENU_THEIGHT ((uint8_t *) \ + "SET TEXT HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_HTAB ((uint8_t *) \ + "SET TAB WIDTH (in columns)\r\n> ") +#define TEXT_MENU_VTAB ((uint8_t *) \ + "SET TAB HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_CWIDTH ((uint8_t *) \ + "SET CHARACTER WIDTH\r\n" \ + "15, 12, 10, 6, 4, 3 CPI\r\n> ") +#define TEXT_MENU_LHEIGHT ((uint8_t *) \ + "SET LINE HEIGHT\r\n" \ + "6, 4, 3, 2 LPI\r\n> ") +#define TEXT_MENU_PAPER ((uint8_t *) \ + "SET_PAPER_TYPE\r\n" \ + "1:continuous 2:single pages\r\n> ") +#define TEXT_MENU_CANCEL ((uint8_t *) \ + " CANCEL\r\n> ") +#define TEXT_MENU_OK ((uint8_t *) \ + " OK\r\n> ") +#define TEXT_MENU_FAIL ((uint8_t *) \ + " FAIL\r\n> ") + +// setting ID in EEPROM + +#define ID_BAUD 1 +#define ID_MODE 2 +#define ID_NL_MODE 3 +#define ID_BS_MODE 4 +#define ID_ENCODING 5 +#define ID_REPLACE 6 +#define ID_BITS 7 +#define ID_LWIDTH 8 +#define ID_LMARGIN 9 +#define ID_RMARGIN 10 +#define ID_PHEIGHT 11 +#define ID_TMARGIN 12 +#define ID_BMARGIN 13 +#define ID_CWIDTH 14 +#define ID_LHEIGHT 15 +#define ID_HTAB 16 +#define ID_VTAB 17 +#define ID_PAPER 18 +#define ID_STYLE 19 +#define ID_FLOW 20 + +// <=25000 <=8192 <=1.500% +// #define UART_DIV_50 20000 // 20000 50.0000 0.000% + +// #define UART_DIV_75 13333 // 13333 1/3 75.0019 +0.010% + +// #define UART_DIV_110 9091 // 9090 10/11 109.9989 -0.001% + + #define UART_DIV_134_5 7435 // 7434.944238 134.4990 -0.001% + + #define UART_DIV_150 6667 // 6666 2/3 149.9925 -0.005% + + #define UART_DIV_200 5000 // 5000 200.0000 0.000% + + #define UART_DIV_300 3333 // 3333 1/3 300.0300 +0.010% + + #define UART_DIV_600 1667 // 1666 2/3 599.8800 -0.020% + + #define UART_DIV_1200 833 // 833 1/3 1200.4802 +0.040% + + #define UART_DIV_1800 556 // 555 5/9 1798.5612 -0.080% + + #define UART_DIV_2400 417 // 416 2/3 2398.0815 -0.080% + + #define UART_DIV_4800 208 // 208 1/3 4807.6923 +0.160% + + #define UART_DIV_7200 139 // 138 8/9 7194.2446 -0.080% + + #define UART_DIV_9600 104 // 104 1/6 9615.3846 +0.160% + + #define UART_DIV_14400 69 // 69 4/9 14492.7536 +0.644% + + #define UART_DIV_19200 52 // 52 1/12 19230.7692 +0.160% + + #define UART_DIV_28800 35 // 34 13/18 28571.4286 -0.794% + + #define UART_DIV_31250 32 // 32 31250.0000 0.000% + + #define UART_DIV_38400 26 // 26 1/24 38461.5384 +0.160% + + #define UART_DIV_57600 17 // 17 17/36 58823.5294 +2.124% - + #define UART_DIV_76800 13 // 13 1/48 76923.0769 +0,160% + + #define UART_DIV_115200 9 // 8 49/72 111111.1111 -3.549% - + #define UART_DIV_125000 8 // 8 125000.0000 0.000% + +// #define UART_DIV_128000 8 // 7 13/16 125000.0000 -2.344% - +// #define UART_DIV_230400 4 // 4 49/144 250000.0000 +8.507% - + #define UART_DIV_250000 4 // 4 250000.0000 0.000% + +// #define UART_DIV_256000 4 // 3 29/32 250000.0000 +2.344% - +// #define UART_DIV_460800 2 // 2 49/284 500000.0000 +8.507% - +// #define UART_DIV_500000 2 // 2 500000.0000 0.000% + +// #define UART_DIV_576000 2 // 1 53/72 500000.0000 -13.194% - +// #define UART_DIV_921600 1 // 1 49/576 1000000.0000 +8.507% - +// #define UART_DIV_1000000 1 // 1 1000000.0000 0.000% + + +#define UART_BAUD_134_5 0 +#define UART_BAUD_150 1 +#define UART_BAUD_200 2 +#define UART_BAUD_300 3 +#define UART_BAUD_600 4 +#define UART_BAUD_1200 5 +#define UART_BAUD_1800 6 +#define UART_BAUD_2400 7 +#define UART_BAUD_4800 8 +#define UART_BAUD_7200 9 +#define UART_BAUD_9600 10 +#define UART_BAUD_14400 11 +#define UART_BAUD_19200 12 +#define UART_BAUD_28800 13 +#define UART_BAUD_31250 14 +#define UART_BAUD_38400 15 +#define UART_BAUD_57600 16 +#define UART_BAUD_76800 17 +#define UART_BAUD_115200 18 +#define UART_BAUD_125000 19 +#define UART_BAUD_250000 20 +#define N_UART_BAUD 21 + +#define UM16_134_5 134 +#define UM16_150 150 +#define UM16_200 200 +#define UM16_300 300 +#define UM16_600 600 +#define UM16_1200 1200 +#define UM16_1800 1800 +#define UM16_2400 2400 +#define UM16_4800 4800 +#define UM16_7200 7200 +#define UM16_9600 9600 +#define UM16_14400 14400 +#define UM16_19200 19200 +#define UM16_28800 28800 +#define UM16_31250 31250 +#define UM16_38400 38400 +#define UM16_57600 57600 +#define UM16_76800 11264 +#define UM16_115200 49664 +#define UM16_125000 59464 +#define UM16_250000 53392 + +#define UART_DATA (7<' +#define R_QUEST CH_003F // '?' +#define R_UNDER CH_005F // '_' +#define R_SPACE CH_0020 // ' ' +#define R_IGNORE CH_NULL // '' + + +#define PAPER_SINGLE 0 +#define PAPER_CONTINUOUS 1 + + +#define STYLE_NORMAL 0b00000000 +#define STYLE_BOLD 0b00000001 +#define STYLE_UNDER 0b00000010 +#define STYLE_UNDER2 0b00000100 +#define STYLE_OVER 0b00001000 +#define STYLE_CROSS 0b00010000 +#define STYLE_STRONG 0b10000000 + + +// some of the fractions were obtained using RIES by Robert Munafo https://mrob.com/pub/ries/ +#define HUNIT_MUL_CH 0 // CHARACTER +#define HUNIT_DIV_CH 0 +#define HUNIT_MUL_MM 300 // MILLIMETRE +#define HUNIT_DIV_MM 127 // 1mm 300/127 +#define HUNIT_MUL_CDP 1 // COMPUTER DECIPOINT +#define HUNIT_DIV_CDP 12 // 1"/720 1/12 +#define HUNIT_MUL_DD 4 // DECIDIDOT +#define HUNIT_DIV_DD 45 // 10mm/266 1500/16891 ~ 4/45 +#define HUNIT_MUL_MIL 3 // MIL +#define HUNIT_DIV_MIL 50 // 1"/1000 3/50 +#define HUNIT_MUL_BMU 1 // BASIC MEASURING UNIT +#define HUNIT_DIV_BMU 20 // 1"/1200 1/20 +#define HUNIT_MUL_UM 3 // MICROMETRE +#define HUNIT_DIV_UM 1270 // 1mm/1000 3/1270 +#define HUNIT_MUL_DP 1 // DECIPOINT +#define HUNIT_DIV_DP 12 // 35mm/996 875/10541 ~ 1/12 + +#define VUNIT_MUL_CH 1 // CHARACTER +#define VUNIT_DIV_CH 0 +#define VUNIT_MUL_MM 60 // MILLIMETRE +#define VUNIT_DIV_MM 127 // 1mm 60/127 +#define VUNIT_MUL_CDP 1 // COMPUTER DECIPOINT +#define VUNIT_DIV_CDP 60 // 1"720 1/60 +#define VUNIT_MUL_DD 4 // DECIDIDOT +#define VUNIT_DIV_DD 225 // 10mm/266 - 300/16891 ~ 4/225 +#define VUNIT_MUL_MIL 3 // MIL +#define VUNIT_DIV_MIL 250 // 1"/1000 3/250 +#define VUNIT_MUL_BMU 1 // BASIC MEASURING UNIT +#define VUNIT_DIV_BMU 100 // 1"/1200 1/100 +#define VUNIT_MUL_UM 3 // MICROMETRE +#define VUNIT_DIV_UM 6350 // 1mm/1000 3/6350 +#define VUNIT_MUL_DP 1 // DECIPOINT +#define VUNIT_DIV_DP 60 // 35mm/996 175/10541 ~ 1/60 + + +// for PFS - PAGE FORMAT SELECTION +// table E.1 in ECMA-48 +// all columns merged into single value + +#define PF_TCOMM_BASIC_TALL 0 +#define PF_TCOMM_BASIC_WIDE 1 +#define PF_A4_BASIC_TALL 2 +#define PF_A4_BASIC_WIDE 3 +#define PF_LETTER_TALL 4 +#define PF_LETTER_WIDE 5 +#define PF_A4_EXT_TALL 6 +#define PF_A4_EXT_WIDE 7 +#define PF_LEGAL_TALL 8 +#define PF_LEGAL_WIDE 9 +#define PF_A4_SHORT 10 +#define PF_A4_LONG 11 +#define PF_B5_SHORT 12 +#define PF_B5_LONG 13 +#define PF_B4_SHORT 14 +#define PF_B4_LONG 15 +#define N_PF 16 + +#define LWIDTH_TCOMM_BASIC_TALL 462 // 92.4 7.7" +#define LWIDTH_TCOMM_BASIC_WIDE 625 // 125 10 5/12" +#define LWIDTH_A4_BASIC_TALL 462 // 92.4 7.7" +#define LWIDTH_A4_BASIC_WIDE 660 // 132 11" +#define LWIDTH_LETTER_TALL 480 // 96 8" +#define LWIDTH_LETTER_WIDE 625 // 125 10 5/12" +#define LWIDTH_A4_EXT_TALL 462 // 92.4 7.7" +#define LWIDTH_A4_EXT_WIDE 660 // 132 11" +#define LWIDTH_LEGAL_TALL 480 // 96 8" +#define LWIDTH_LEGAL_WIDE 810 // 162 13.5" +#define LWIDTH_A4_SHORT 450 // 90 7.5" +#define LWIDTH_A4_LONG 655 // 131 10 11/12" +#define LWIDTH_B5_SHORT 375 // 75 6.25" +#define LWIDTH_B5_LONG 555 // 111 9.25" +#define LWIDTH_B4_SHORT 555 // 111 9.25" +#define LWIDTH_B4_LONG 785 // 157 13 1/12" + +#define PHEIGHT_TCOMM_BASIC_TALL 110 // 55 9 1/6" +#define PHEIGHT_TCOMM_BASIC_WIDE 76 // 38 6 1/3" +#define PHEIGHT_A4_BASIC_TALL 118 // 59 9 5/6" +#define PHEIGHT_A4_BASIC_WIDE 76 // 38 6 1/3" +#define PHEIGHT_LETTER_TALL 112 // 56 9 1/3" +#define PHEIGHT_LETTER_WIDE 80 // 40 6 2/3" +#define PHEIGHT_A4_EXT_TALL 132 // 63 11" +#define PHEIGHT_A4_EXT_WIDE 88 // 44 7 1/3" +#define PHEIGHT_LEGAL_TALL 148 // 74 12 1/3" +#define PHEIGHT_LEGAL_WIDE 80 // 40 6 2/3" +#define PHEIGHT_A4_SHORT 118 // 59 9 5/6" +#define PHEIGHT_A4_LONG 76 // 38 6 1/3" +#define PHEIGHT_B5_SHORT 98 // 49 8 1/6" +#define PHEIGHT_B5_LONG 64 // 32 5 1/13" +#define PHEIGHT_B4_SHORT 114 // 59 9.5" +#define PHEIGHT_B4_LONG 98 // 49 8 1/6" + + +#define WIDTH_15 4 // 1/15 " +#define WIDTH_12 5 // 1/12 " +#define WIDTH_10 6 // 1/10 " +#define WIDTH_6 10 // 1/6 " +#define WIDTH_4_5 13 // 2/9 " 13 1/3 +#define WIDTH_4 15 // 1/4 " +#define WIDTH_3 20 // 1/3 " +#define N_CWIDTH 7 + +#define HEIGHT_6 2 // 1/6 " 2 +#define HEIGHT_4 3 // 1/4 " 3 +#define HEIGHT_3 4 // 1/3 " 4 +#define HEIGHT_12 1 // 1/12 " 1 +#define HEIGHT_8 2 // 3.75mm 1.5 +#define HEIGHT_6M 2 // 5mm 2 46/127 +#define HEIGHT_4M 4 // 7.5mm 3 69/127 +#define HEIGHT_3M 5 // 10mm 4 92/127 +#define HEIGHT_12M 1 // 2.5mm 1 23/127 +#define HEIGHT_2 6 // 1/2 " 6 +#define N_LHEIGHT 10 + +#define WIDTH_NARROW WIDTH_15 +#define WIDTH_NORMAL WIDTH_12 +#define WIDTH_WIDE WIDTH_10 + +#define HEIGHT_NORMAL HEIGHT_6 + +/* +Text positions and default margins on machine + +12CPI: +0 1 2 3 4 5 6 7 8 9 10 +012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 +XXXXXXXXXXXX XXXXXXXXXXXXXXXXXX + +10CPI: +0 1 2 3 4 5 6 7 8 +012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +XXXXXXXXXX XXXXXXXXXXXXXXX + +unit is 1/60", width is 10". Default left margin is 1", right is 1.5". +I'm keeping out of first and last 12CPI columns, denying their existence +*/ + +#define HPOS_LIMIT ((108-2) * WIDTH_NORMAL) +#define VPOS_LIMIT (144 * HEIGHT_NORMAL) +#define DEFAULT_LWIDTH (92 * WIDTH_NORMAL) +#define DEFAULT_PHEIGHT (72 * HEIGHT_NORMAL) +#define DEFAULT_LMARGIN ((12-1) * WIDTH_NORMAL) +#define DEFAULT_LMARGIN_AIM (0 * WIDTH_NORMAL) +#define DEFAULT_RMARGIN ((90-1) * WIDTH_NORMAL) +#define DEFAULT_RMARGIN_AIM ((80 * WIDTH_NORMAL)+DEFAULT_LMARGIN_AIM) +#define DEFAULT_TMARGIN (0 * HEIGHT_NORMAL) +#define DEFAULT_BMARGIN ((56 * HEIGHT_NORMAL)+DEFAULT_TMARGIN) +#define DEFAULT_TWIDTH_CH 4 +#define DEFAULT_THEIGHT_CH 4 + +// for PFS - PAGE FORMAT SELECTION again +#define LMARGIN_PRESET (12 * WIDTH_NORMAL) +#define RMARGIN_PRESET (2 * WIDTH_NORMAL) + +// size in bytes of table to keep track of TAB positions. +#define N_HTAB (((HPOS_LIMIT-1)/8)+1) +#define N_VTAB (((VPOS_LIMIT-1)/8)+1) + + +// timing stuff + +// Frequency of main interrupt, values for prescaler and counter +#define INT_PRE 2 // 8MHz / 8 = 1MHz +#define INT_DIV 167 // 1MHz / 167 = 5.988kHz +// Based on that derive frequency for triggers of LED and printing action +// Printing 1 character takes 4+ cycles +#define PRINT_DIV 176 // 1MHz / 167 / 176 = 34.0228Hz = 4 * 8.5057Hz +#define LED_DIV 599 // 1MHz / 167/ 599 = 9.9967Hz +// how many cycles of delay (wait for Carriage Return) 1 character introduces: +#define PRINT_DELAY 1 // 2? + +#define TIME_1MS 6 +#define TIME_10MS 60 +#define TIME_100MS 600 +#define TIME_1S 6000 + +#define SCAN_HOLD 3 // how long state must be stable +#define SCAN_DEBOUNCE 3 // 3 * 10ms = 30ms +#define SCAN_DELAY 70 // 70 * 10ms = 700ms +#define SCAN_REPEAT 12 // 12 * 10ms = 120ms +// ~10ms is the total period coming from the typewriter + + +// buffer sizes +#define N_INCOME_BUFFER 256 // incoming characters +#define N_OUTCOME_BUFFER 64 // outcoming characters +#define N_PRINT_BUFFER 128 // outcoming key presses +#define N_SCAN_BUFFER 64 // incoming key presses +#define N_ESC_BUFFER 64 // control string / sequence + +#define INCOME_BUFFER_LOW 8 // for XON / CTS +#define INCOME_BUFFER_HIGH 208 // for XOFF / ~CTS + + +// control for allowing / disallowing sleep mode +#define WAKEUP_INCOME 0b00000001 +#define WAKEUP_OUTCOME 0b00000010 +#define WAKEUP_SCAN 0b00000100 + + +#define EEPROM_SIZE (4 * 1024) + + +/* +IO + ATmega1284 + +-------\/-------+ + /----- 0 |*1 B0 A0 40| 70 /----- + RX |14 D0 C5 27| 05 / + <- TX |15 D1 C4 26| 04/KEYBOARD + <- FLOW |16 D2 C3 25| 03\ COLUMN + -> FLOW |17 D3 C2 24| 02 \ + <- /LED |18 D4 C1 23| 01 \ + <- /KEY |19 D5 C0 22| 00 \----- +<- /EN_KEYB |20 D6 C7 21| /EN_PRINT -> + +----------------+ +*/ + +// port A, keyboard row +#define PORT_ROW PORTA +#define DDR_ROW DDRA +#define PIN_ROW PINA + +// port C, keyboard column +#define PORT_COL PORTC +#define DDR_COL DDRC +#define PIN_COL PINC + +// port B, key output select +#define PORT_KEY PORTB +#define DDR_KEY DDRB + +// port D, control of state, active low +#define PORT_CTRL PORTD +#define DDR_CTRL DDRD + +#define LED 0b00010000 // out +#define KEY 0b00100000 // out +#define EN_PRINT 0b01000000 // out +#define EN_KEYB 0b10000000 // out + +#define MASK_CTRL (LED|KEY|EN_PRINT|EN_KEYB) + +// port D, communication +#define PORT_COMM PORTD +#define DDR_COMM DDRD +#define PIN_COMM PIND + +#define RX 0b00000001 // in +#define TX 0b00000010 // out +#define SYNC_IN 0b00000100 // in +#define SYNC_OUT 0b00001000 // out + +#define MASK_COMM (RX|TX|SYNC_IN|SYNC_OUT) + + +// to simplify keeping track of buffer indexing +#define CTRL_IND (buffer+1), &buffer_pos, &p_ind, &sp_ind + +// common actions on buffer pointers +// W write pointer +// R read pointer +// P any pointer +// N buffer size +#define ADVANCE_BP(P, N) ((P<(N-1)) ? (++P) : (P=0)) +#define DIFF_BP(W, R, N) ((W> 8); + // UBRR0L = (uint8_t) ((UART_DIV[baud]-1) & 0xff); + UBRR0 = UART_DIV[baud]-1; + UCSR0A = (1<= PRINT_DIV-1) + { + print_timer = 0; + handle_print(); + } + else + ++print_timer; + + // LED control + if (led_timer >= LED_DIV-1) + { + led_timer = 0; + if (set_led) // there was request + { + PORT_CTRL &= ~LED; + if (set_led > led_on) + led_on = set_led; + set_led = 0; + } + else if(led_on) // keep until out of time + { + --led_on; + if (!led_on) + PORT_CTRL |= LED; + } + } + ++led_timer; + + // as DCE, constant update is needed, + // CTS depents on buffer state and RTS + if ((flow & FLOW_HW) == FLOW_HD_DCE) + update_flowcontrol_hw(); + + ++main_timer; + // TODO + // goto_sleep(); +} + + +/* kezboard input */ + +static inline void scan_keyboard (void) +{ + static uint8_t base_state [8] = {0,0,0,0,0,0,0,0}; + static uint8_t last_state [8] = {0,0,0,0,0,0,0,0}; + + static uint8_t shift_state = 0; + static uint8_t code_state = 0; + + static uint8_t last_row = 0b00000000; + static uint8_t last_col = 0b00000000; + static uint8_t hold_count = 0; + static uint8_t key_debounce[8] = {0,0,0,0,0,0,0,0}; + static uint8_t key_repeat[8] = {0,0,0,0,0,0,0,0}; + + uint8_t row, col; + uint8_t ind, ind_base, ind_off; + uint8_t filtered_state; + + uint8_t send_event = 0; + + // get keyboard state + col = PIN_COL; + row = PIN_ROW; + + if (row == last_row) // keep measuring pulse length + ++hold_count; + else // state changed; react + { + if (hold_count >= SCAN_HOLD) // pulse was long enough; + { + // now handle state from previous iteration, before change + + // get row number, accept only single row selected, prepare base value + switch(last_row) + { + case KEYB_0: + ind = 0; + ind_base = KEYB_ROW_0; + break; + case KEYB_1: + ind = 1; + ind_base = KEYB_ROW_1; + break; + case KEYB_2: + ind = 2; + ind_base = KEYB_ROW_2; + break; + case KEYB_3: + ind = 3; + ind_base = KEYB_ROW_3; + break; + case KEYB_4: + ind = 4; + ind_base = KEYB_ROW_4; + break; + case KEYB_5: + ind = 5; + ind_base = KEYB_ROW_5; + break; + case KEYB_6: + ind = 6; + ind_base = KEYB_ROW_6; + break; + case KEYB_7: + ind = 7; + ind_base = KEYB_ROW_7; + break; + default: + ind = 0xff; + } + + // there was single row selected, signal is valid + if (ind < 8) + { + // do some debouncing + if (last_col != last_state[ind]) + key_debounce[ind] = 0; + else + { + if(key_debounce[ind] < SCAN_DEBOUNCE) + { + ++key_debounce[ind]; + // ok, debouncing finished, key change detected + if(key_debounce[ind] == SCAN_DEBOUNCE) + { + // prepare state, prepare repeat counter + base_state[ind] = last_col; + key_repeat[ind] = SCAN_DEBOUNCE - 1; + send_event = 1; + } + } + } + + // handle repeated event after long press + if (key_repeat[ind] >= SCAN_DELAY) + { + key_repeat[ind] -= SCAN_REPEAT; + send_event = 1; + } + ++key_repeat[ind]; + + // ok, now prepare and send a key press event + if (send_event) + { + send_event=0; + filtered_state = base_state[ind]; + // special handling for SHIFT and CODE keys + if (ind==KEYB_MOD_IND) + { + shift_state = (filtered_state & KEYB_SHIFT_BIT) ? KEYB_SHIFT : 0; + code_state = (filtered_state & KEYB_CODE_BIT) ? KEYB_CODE : 0; + filtered_state &= ~(KEYB_SHIFT_BIT | KEYB_CODE_BIT); + } + // get column number, accept single row only, prepare offset value + switch (filtered_state) + { + case KEYB_0: + ind_off = KEYB_COL_0; + break; + case KEYB_1: + ind_off = KEYB_COL_1; + break; + case KEYB_2: + ind_off = KEYB_COL_2; + break; + case KEYB_3: + ind_off = KEYB_COL_3; + break; + case KEYB_4: + ind_off = KEYB_COL_4; + break; + case KEYB_5: + ind_off = KEYB_COL_5; + break; + case KEYB_6: + ind_off = KEYB_COL_6; + break; + case KEYB_7: + ind_off = KEYB_COL_7; + break; + default: + ind_off = 0xff; + break; + } + // single column, signal still valid + if (ind_off <= KEYB_COL_7) + { + // generate the correct event + add_scan(ind_base | ind_off | shift_state | code_state); + } + } + last_state[ind] = last_col; + } + } + hold_count=0; + } + last_row = row; + last_col = col; +} + +void add_scan (const uint8_t key) +{ + // buffer is full, keyboard event will be lost + if (FULL_BP(scan_w, scan_r, N_SCAN_BUFFER)) + { + set_led = 10; + set_alarm = 1; + return; + } + + scan_buffer[scan_w] = key; + ADVANCE_BP(scan_w, N_SCAN_BUFFER); + + // can't sleep when there are keys to handle + cancel_sleep(WAKEUP_SCAN); +} + +void handle_scan (void) +{ + uint8_t key; + uint8_t ch; + uint16_t uni_ch; + uint8_t uni_bytes; + uint8_t uni_buffer[3]; + + static uint8_t ctrl = 0; + + cli(); + if (EMPTY_BP(scan_w, scan_r, N_SCAN_BUFFER)) + { + sei(); + allow_sleep(WAKEUP_SCAN); + } + else + { + sei(); + + key = scan_buffer[scan_r]; + ADVANCE_BP(scan_r, N_SCAN_BUFFER); + + // first event since startup is a key press + // start working as a normal typewriter + // (unless special combination, then be terminal instead) + if (mode == MODE_WAIT) + { + if (key & (KEYB_SHIFT|KEYB_CODE)) + become_terminal(); + else + become_typewriter(); + } + + // only handle keyboard input if in terminal mode + if (mode & MODE_TERM) + { + switch (key) + { + // new page + case QMENU_PAGE: // new page inserted + if (!wait_page) + break; + case QMENU_FPAGE: // force reset to page top + vpos = tmargin; + vpos_aim = tmargin; + wait_page = 0; + set_alarm = 1; + break; + // some style change + case QMENU_BOLD: + toggle_bold(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_UNDER: + toggle_under(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_UNDER2: + toggle_under2(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_CROSS: + toggle_cross(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_OVER: + toggle_over(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_STRONG: + set_style_strong(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case QMENU_WEAK: + set_style_weak(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + // line & char. spacing + case QMENU_6LPI: + set_lheight(HEIGHT_6); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case QMENU_4LPI: + set_lheight(HEIGHT_4); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case QMENU_3LPI: + set_lheight(HEIGHT_3); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case QMENU_10CPI: + set_cwidth(WIDTH_10); + store_single_config(ID_CWIDTH); + set_alarm=1; + break; + case QMENU_12CPI: + set_cwidth(WIDTH_12); + store_single_config(ID_CWIDTH); + set_alarm=1; + break; + // hex + case QMENU_HEX: + set_mode(mode ^ MODE_HEX); + store_single_config(ID_MODE); + set_alarm=1; + break; + // local echo + case QMENU_ECHO: + set_mode(mode ^ MODE_ECHO); + store_single_config(ID_MODE); + set_alarm=1; + break; + // paper type + case QMENU_PAPER: + if (paper == PAPER_SINGLE) + paper = PAPER_CONTINUOUS; + else + paper = PAPER_SINGLE; + store_single_config(ID_PAPER); + set_alarm=1; + break; + // exit terminal mode, be a normal typewriter now + case QMENU_EXIT: + become_typewriter(); + break; + // not a function key + default: + // First, perform menu handling, if relevant + if (handle_menu(key)) + ctrl = 0; + else + { + switch(key) + { + case KEY_BACK: // backspace + add_ch((bs_mode & BS_BS) ? 0x08 : 0x7f); + break; + case KEY_ERASE1: // delete + add_ch((bs_mode & BS_DEL) ? 0x7f : 0x08); + break; + case KEY_ERASEW: // ctrl + ctrl = 1; + break; + case KEY_RETURN: // newline + case SKEY_RETURN: + if (nl_mode & NL_SEND_CR) + add_ch('\r'); + if (nl_mode & NL_SEND_LF) + add_ch('\n'); + break; + default: // "normal" key; just consult keymap + if (encoding & ENC_UNI) // UTF-8 + { + uni_ch = KEYMAP_UNI[key]; + + if (uni_ch >= 0x0080) // multi-byte code point + { + uni_buffer[0] = 0b10000000; + if (uni_ch >= 0x0800) + { + uni_bytes = 3; + uni_buffer[1] = 0b10000000; + uni_buffer[2] = 0b11100000; + } + else + { + uni_bytes = 2; + uni_buffer[1] = 0b11000000; + } + uni_buffer[0] |= uni_ch & 0b00111111; + uni_ch >>= 6; + uni_buffer[1] |= uni_ch & 0b00111111; + uni_ch >>= 6; + uni_buffer[2] |= uni_ch; + while (uni_bytes) + { + --uni_bytes; + add_ch(uni_buffer[uni_bytes]); + } + } + else if (uni_ch) + { + if (ctrl) // CTRL + key + { + uni_ch &= 0x1f; + ctrl = 0; + } + add_ch(uni_ch); + } + } + else + { + ch = KEYMAP_CP[key]; + if (ch) + { + if (ctrl) // CTRL + key + { + ch &= 0x1f; + ctrl = 0; + } + add_ch(ch); + } + } + break; + } + } + } + } + } +} + + +/* menu */ + +uint8_t handle_menu (const uint8_t key) +{ + static uint8_t menu_active = 0; + static uint8_t function = MENU_NONE; + static uint8_t allow_output = 0; + static uint16_t value=0; + uint8_t x; + + if (!menu_active) // we're not in menu yet + { + if (key == MENU_ENTER) // let's enter menu + { + menu_active = 1; + function = MENU_NONE; + allow_output = 0; + set_alarm = 1; + } + } + else if (function == MENU_NONE) // in menu, no function chosen + { + function = key; + value = 0; + switch (key) + { + case MENU_ENTER: // enable printing in menu + case MENU_OUTPUT: + function = MENU_NONE; + allow_output = 1; + add_income_str(TEXT_MENU_LIST, 1); + set_alarm = 1; + break; + case MENU_EXIT: // leave the menu + case MENU_CONFIRM: + menu_active = 0; + if (allow_output) add_income_str(TEXT_MENU_EXIT, 1); + set_alarm = 3; + // we don't want to return actual status this time + // it would treat the menu exit key as normal terminal action + return 1; + case MENU_BAUD: + if (allow_output) add_income_str(TEXT_MENU_BAUD, 1); + break; + case MENU_BITS: + if (allow_output) add_income_str(TEXT_MENU_BITS, 1); + break; + case MENU_FLOW: + if (allow_output) add_income_str(TEXT_MENU_FLOW, 1); + break; + case MENU_ECHO: + if (allow_output) add_income_str(TEXT_MENU_ECHO, 1); + break; + case MENU_DELETE: + if (allow_output) add_income_str(TEXT_MENU_DELETE, 1); + break; + case MENU_NEWLINE: + if (allow_output) add_income_str(TEXT_MENU_NEWLINE, 1); + break; + case MENU_REPLACE: + if (allow_output) add_income_str(TEXT_MENU_REPLACE, 1); + break; + case MENU_ENCODING: + if (allow_output) add_income_str(TEXT_MENU_ENCODING, 1); + break; + case MENU_PWIDTH: + if (allow_output) add_income_str(TEXT_MENU_PWIDTH, 1); + break; + case MENU_LMARGIN: + if (allow_output) add_income_str(TEXT_MENU_LMARGIN, 1); + break; + case MENU_RMARGIN: + if (allow_output) add_income_str(TEXT_MENU_RMARGIN, 1); + break; + case MENU_TWIDTH: + if (allow_output) add_income_str(TEXT_MENU_TWIDTH, 1); + break; + case MENU_PHEIGHT: + if (allow_output) add_income_str(TEXT_MENU_PHEIGHT, 1); + break; + case MENU_TMARGIN: + if (allow_output) add_income_str(TEXT_MENU_TMARGIN, 1); + break; + case MENU_BMARGIN: + if (allow_output) add_income_str(TEXT_MENU_BMARGIN, 1); + break; + case MENU_THEIGHT: + if (allow_output) add_income_str(TEXT_MENU_THEIGHT, 1); + break; + case MENU_HTAB: + if (allow_output) add_income_str(TEXT_MENU_HTAB, 1); + break; + case MENU_VTAB: + if (allow_output) add_income_str(TEXT_MENU_VTAB, 1); + break; + case MENU_CWIDTH: + if (allow_output) add_income_str(TEXT_MENU_CWIDTH, 1); + break; + case MENU_LHEIGHT: + if (allow_output) add_income_str(TEXT_MENU_LHEIGHT, 1); + break; + case MENU_PAPER: + if (allow_output) add_income_str(TEXT_MENU_PAPER, 1); + break; + default: + function = MENU_NONE; + } + if (function != MENU_NONE) + set_alarm = 2; + } + else // in menu, function already chosen + { + switch(key) + { + case KEY_0: // digit; update value + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + x=KEYMAP_LIST[0][key]; + if(allow_output) + add_income(x, 1); + value *= 10; + value += x-0x30; + set_alarm = 1; + break; + case MENU_EXIT: // cancel input + function = MENU_NONE; + if(allow_output) + add_income_str(TEXT_MENU_CANCEL, 1); + set_alarm = 2; + break; + case MENU_ENTER: // enable printing, cancel input + case MENU_OUTPUT: + function = MENU_NONE; + if(allow_output) + add_income_str(TEXT_MENU_LIST, 1); + set_alarm = 2; + case MENU_CONFIRM: // confirm value + switch (function) + { + case MENU_BAUD: + switch (value) + { + case UM16_134_5: + value = UART_BAUD_134_5; + break; + case UM16_150: + value = UART_BAUD_150; + break; + case UM16_200: + value = UART_BAUD_200; + break; + case UM16_300: + value = UART_BAUD_300; + break; + case UM16_600: + value = UART_BAUD_600; + break; + case UM16_1200: + value = UART_BAUD_1200; + break; + case UM16_1800: + value = UART_BAUD_1800; + break; + case UM16_2400: + value = UART_BAUD_2400; + break; + case UM16_4800: + value = UART_BAUD_4800; + break; + case UM16_7200: + value = UART_BAUD_7200; + break; + case UM16_9600: + value = UART_BAUD_9600; + break; + case UM16_14400: + value = UART_BAUD_14400; + break; + case UM16_19200: + value = UART_BAUD_19200; + break; + case UM16_28800: + value = UART_BAUD_28800; + break; + case UM16_31250: + value = UART_BAUD_31250; + break; + case UM16_38400: + value = UART_BAUD_38400; + break; + case UM16_57600: + value = UART_BAUD_57600; + break; + case UM16_76800: + value = UART_BAUD_76800; + break; + case UM16_115200: + value = UART_BAUD_115200; + break; + case UM16_125000: + value = UART_BAUD_125000; + break; + case UM16_250000: + value = UART_BAUD_250000; + break; + case UART_BAUD_134_5: + case UART_BAUD_150: + case UART_BAUD_200: + case UART_BAUD_300: + case UART_BAUD_600: + case UART_BAUD_1200: + case UART_BAUD_1800: + case UART_BAUD_2400: + case UART_BAUD_4800: + case UART_BAUD_7200: + case UART_BAUD_9600: + case UART_BAUD_14400: + case UART_BAUD_19200: + case UART_BAUD_28800: + case UART_BAUD_31250: + case UART_BAUD_38400: + case UART_BAUD_57600: + case UART_BAUD_76800: + case UART_BAUD_115200: + case UART_BAUD_125000: + case UART_BAUD_250000: + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_baudrate(value); + store_single_config(ID_BAUD); + value = 0; + } + break; + case MENU_BITS: + switch (value) + { + case 1: + value = UART_8N1; + break; + case 2: + value = UART_8E1; + break; + case 3: + value = UART_8O1; + break; + case 4: + value = UART_8N2; + break; + case 5: + value = UART_8E2; + break; + case 6: + value = UART_8O2; + break; + case 7: + value = UART_7N1; + break; + case 8: + value = UART_7E1; + break; + case 9: + value = UART_7O1; + break; + case 10: + value = UART_7N2; + break; + case 11: + value = UART_7E2; + break; + case 12: + value = UART_7O2; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_serial_mode(value); + store_single_config(ID_BITS); + value = 0; + } + break; + case MENU_FLOW: + switch (value) + { + case 1: // RTR/CTS + value = (flow & ~FLOW_HW) | FLOW_FD; + break; + case 2: // RTS/CTS, we're the DTE + value = (flow & ~FLOW_HW) | FLOW_HD_DTE; + break; + case 3: // RTS/CTS, we're the DCE + value = (flow & ~FLOW_HW) | FLOW_HD_DCE; + break; + case 4: + value = (flow & ~FLOW_HW) | FLOW_NONE; + break; + case 5: + value = (flow & ~FLOW_SW) | FLOW_XONOFF; + break; + case 6: + value = (flow & ~FLOW_SW) | FLOW_NONE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_flowcontrol(value); + store_single_config(ID_FLOW); + value = 0; + } + break; + case MENU_ECHO: + switch (value) + { + case 1: + set_mode(mode | MODE_ECHO); + break; + case 2: + set_mode(mode & ~MODE_ECHO); + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_MODE); + value = 0; + } + break; + case MENU_NEWLINE: + switch (value) + { + case 1: // receive CR -> CR LF + nl_mode = (nl_mode & ~NL_IMPLICIT_CR) | NL_IMPLICIT_LF; + break; + case 2: // receive LF -> CR LF + nl_mode = (nl_mode & ~NL_IMPLICIT_LF) | NL_IMPLICIT_CR; + break; + case 3: // receive CR or LF -> CR LF + nl_mode |= NL_CATCH_ALL; + break; + case 4: // no change + nl_mode &= ~NL_CATCH_ALL; + break; + case 5: // send CR + nl_mode = (nl_mode & ~NL_SEND_LF) | NL_SEND_CR; + break; + case 6: // send LF + nl_mode = (nl_mode & ~NL_SEND_CR) | NL_SEND_LF; + break; + case 7: // send CR LF + nl_mode |= NL_SEND_CRLF; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_MODE); + value = 0; + } + break; + case MENU_DELETE: + switch (value) + { + case 1: // BACKSPACE is 08 + bs_mode |= BS_BS; + break; + case 2: // BACKSPACE is 7F + bs_mode &= ~BS_BS; + break; + case 3: // DELETE is 7F + bs_mode |= BS_DEL; + break; + case 4: // DELETE is 08 + bs_mode &= ~BS_DEL; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_BS_MODE); + value = 0; + } + break; + case MENU_REPLACE: + switch (value) + { + case 1: // + replace = REPLACE_SYMBOL; + break; + case 2: // ? + replace = REPLACE_QUEST; + break; + case 3: // _ + replace = REPLACE_UNDER; + break; + case 4: // SPACE + replace = REPLACE_SPACE; + break; + case 5: // IGNORE + replace = REPLACE_IGNORE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_REPLACE); + value = 0; + } + break; + case MENU_ENCODING: + switch (value) + { + case 1: + value = ENC_ISO8859_1; + break; + case 2: + value = ENC_ISO8859_2; + break; + case 3: + value = ENC_ISO8859_3; + break; + case 4: + value = ENC_ISO8859_4; + break; + case 9: + value = ENC_ISO8859_9; + break; + case 10: + value = ENC_ISO8859_10; + break; + case 13: + value = ENC_ISO8859_13; + break; + case 15: + value = ENC_ISO8859_15; + break; + case 16: + value = ENC_ISO8859_16; + break; + case 1250: + value = ENC_CP1250; + break; + case 852: + value = ENC_CP852; + break; + case 8: // UTF-8 + value = encoding | ENC_UNI; + break; + default: + value = 0xffff; + break; + } + if (value != 0xffff) + { + set_encoding(value); + store_single_config(ID_ENCODING); + value = 0; + } + break; + case MENU_PWIDTH: + if (value == 0) + value = 0xffff; + else + { + value *= cwidth_aim; + if (value > HPOS_LIMIT) + value = 0xffff; + else + { + set_lwidth(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + } + break; + case MENU_LMARGIN: + value *= cwidth_aim; + if (value > (HPOS_LIMIT - cwidth_aim)) + value = 0xffff; + else + { + set_lmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + break; + case MENU_RMARGIN: + value *= cwidth_aim; + if (value > (lwidth - cwidth_aim)) + value = 0xffff; + else + { + value = lwidth - value; + set_rmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + break; + case MENU_TWIDTH: + if (value == 0) + value = 0xffff; + else + { + value *= cwidth_aim; + value += lmargin_aim; + if (value > HPOS_LIMIT) + value = 0xffff; + else + { + set_rmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + } + break; + case MENU_PHEIGHT: + if (value == 0) + value = 0xffff; + else + { + value *= lheight; + if (value > VPOS_LIMIT) + value = 0xffff; + else + { + set_pheight(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + } + break; + case MENU_TMARGIN: + value *= lheight; + if (value > (VPOS_LIMIT - lheight)) + value = 0xffff; + else + { + set_tmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + break; + case MENU_BMARGIN: + value *= lheight; + if (value > (pheight - lheight)) + value = 0xffff; + else + { + value = pheight - value; + set_bmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + break; + case MENU_THEIGHT: + if (value == 0) + value = 0xffff; + else + { + value *= lheight; + value += tmargin; + if (value > VPOS_LIMIT) + value = 0xffff; + else + { + set_bmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + } + break; + case MENU_HTAB: + if (value == 0) + value = 0xffff; + else + { + set_twidth_ch(value); + store_single_config(ID_HTAB); + value = 0; + } + break; + case MENU_VTAB: + if (value == 0) + value = 0xffff; + else + { + set_theight_ch(value); + store_single_config(ID_VTAB); + value = 0; + } + break; + case MENU_CWIDTH: + switch (value) // CPI + { + case 15: + value = WIDTH_15; + break; + case 12: + value = WIDTH_12; + break; + case 10: + value = WIDTH_10; + break; + case 6: + value = WIDTH_6; + break; + case 4: + value = WIDTH_4; + break; + case 3: + value = WIDTH_3; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_cwidth(value); + store_single_config(ID_CWIDTH); + value = 0; + } + break; + case MENU_LHEIGHT: + switch (value) // LPI + { + case 6: + value = HEIGHT_6; + break; + case 4: + value = HEIGHT_4; + break; + case 3: + value = HEIGHT_3; + break; + case 2: + value = HEIGHT_2; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_lheight(value); + store_single_config(ID_CWIDTH); + value = 0; + } + break; + case MENU_PAPER: + switch (value) + { + case 1: + value = PAPER_CONTINUOUS; + break; + case 2: + value = PAPER_SINGLE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + paper = value; + store_single_config(ID_PAPER); + value = 0; + } + break; + default: + value = 1; + } + function = MENU_NONE; + if (!value) + { + if(allow_output) + add_income_str(TEXT_MENU_OK, 1); + set_alarm = 2; + } + else + { + if(allow_output) + add_income_str(TEXT_MENU_FAIL, 1); + set_alarm = 5; + } + break; + } + } + + return menu_active; +} + + +/* keyboard output */ + +void add_print_key (const uint8_t key) +{ + while (FULL_BP(print_w, print_r, N_PRINT_BUFFER)) + { + // wait for space in buffer + // interrupt will do it + } + print_buffer[print_w] = key; + ADVANCE_BP(print_w, N_PRINT_BUFFER); + + last_print_time = main_timer; +} + +void add_print_ch (uint8_t const * const ch) +{ + uint8_t const * p; + uint8_t count; + + // prepare position before + // often redundant but not always + adjust_print_pos(); + + p = ch; + + // replacement symbol for unknown char + if (p == CH_UNKN) + p = REPLACE[replace]; + + // nothing to print + if (*p == 0) + return; + + // add key sequence to buffer + for (count = *p; count!=0; --count) + { + ++p; + add_print_key(*p); + } + + // manually apply styles not handled automatically + if (style & STYLE_UNDER) + { + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + } + if (style & (STYLE_CROSS|STYLE_OVER)) + { + add_print_key(CODE_HALFUP); + if (style & STYLE_CROSS) + { + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + } + if (style & STYLE_OVER) + { + add_print_key(CODE_HALFUP); + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + add_print_key(CODE_HALFDOWN); + } + add_print_key(CODE_HALFDOWN); + } + if (style & STYLE_UNDER2) + { + add_print_key(CODE_HALFDOWN); + add_print_key(KEY_BACK); + add_print_key(SKEY_EQ); + add_print_key(CODE_HALFUP); + } + + // adjust position + hpos += cwidth; + hpos_aim += cwidth_aim; + + // moved out of line; adjust again + if ((hpos_aim + cwidth_aim) > rmargin_aim) + adjust_print_pos(); +} + +// low level; no newlines & stuff + +static inline void add_print_ch_ASCII (const uint8_t ch) +{ + add_print_ch(CH_ASCII[ch & 0b01111111]); +} + +static inline void add_print_ch_CP (const uint8_t ch) +{ + if (ch & 0b10000000) + add_print_ch(CH_CP[ch]); + else + add_print_ch(CH_ASCII[ch]); +} + +static inline void add_print_ch_UNI (const uint32_t ch) +{ + if (ch < CH_LIMIT) + add_print_ch(UNI_TABLE[ch]); + else + add_print_ch(CH_UNKN); +} + +void add_print_str_ASCII (uint8_t const * str) +{ + uint8_t const * p; + + for (p = str; *p != 0x00; ++p) + add_print_ch_ASCII(*p); +} + +void add_print_str_CP (uint8_t const * str) +{ + uint8_t const * p; + + for (p = str; *p != 0x00; ++p) + add_print_ch_CP(*p); +} + +void add_print_dec ( + const uint32_t value, + const uint8_t min_digits +) +{ + uint8_t text[11]; + uint8_t x; + + x = make_dec_string( + text, + value, + min_digits, + 10 + ); + text[x] = 0x00; + add_print_str_ASCII(text); +} + +void add_print_hex ( + const uint32_t value, + const uint8_t min_digits +) +{ + uint8_t text[9]; + uint8_t x; + + x = make_hex_string( + text, + value, + min_digits, + 8, + 1 + ); + text[x] = 0x00; + add_print_str_ASCII(text); +} + +static inline void handle_print (void) +{ + static uint8_t phase=0; + static uint8_t count=0; + static uint8_t delay=255; + static uint8_t alarm=0; + + uint8_t key; + static uint8_t prev = CODE_BELL; + + if (set_alarm) // there was request for buzzer + { + if (set_alarm > alarm) + alarm = set_alarm; + set_alarm = 0; + } + + if (!phase) // free to print next key + { + if (delay || alarm) + { + last_print_time = main_timer; + + if (alarm) // insert buzzer action + { + PORT_KEY = CODE_BELL; + phase = 3; + --alarm; + } + if (delay) // wait for Carriage Return + --delay; + } + else if (!(mode & MODE_TERM)) // we're not in terminal mode + { + } + else if (NOT_EMPTY_BP(print_w, print_r, N_PRINT_BUFFER)) // key press available in buffer + { + key = print_buffer[print_r]; + ADVANCE_BP(print_r, N_PRINT_BUFFER); + + if ((key == CODE_STEPLEFT_EXTRA) && (cwidth == WIDTH_NORMAL)) + { + // 10 CPI has 6 microspaces in char, 12 CPI has 5 + // 6th microspace must be ignored for 12 CPI + } + else + { + last_print_time = main_timer; + + PORT_KEY = key; // select key, press SHIFT, CODE + phase = 3; + + switch (key) + { + case CODE_RETURN: // carriage return; activate the delay + case KEY_RETURN: + delay = count; + count = 0; + break; + case KEY_BACK: // going left; reduce CR delay + if (count >= PRINT_DELAY) + count -= PRINT_DELAY; + else + count = 0; + break; + case CODE_STEPLEFT: // minimally going left + case CODE_HALFUP: // staying in place; don't change CR delay + case CODE_HALFDOWN: + break; + default: // going right (???); increase CR delay + if (count < 0xff - PRINT_DELAY) + count += PRINT_DELAY; + else + count = 0xff; + if (style & STYLE_BOLD) // multi-strike takes more time + phase += 2; + } + switch(prev) // movement back takes extra time + { + case CODE_STEPLEFT: + case CODE_STEPLEFT_EXTRA: + case CODE_HALFUP: + phase += 2; // slightly increase wait before key + } + prev = key; + } + } + else // no key waiting + { + PORT_KEY &= ~(KEYB_SHIFT | KEYB_CODE); // release SHIFT and CODE + } + } + else // continue ongoing key action + { + last_print_time = main_timer; + + if (phase == 3) // key down + PORT_CTRL &= ~KEY; + else if (phase == 1) // key up + PORT_CTRL |= KEY; + --phase; + } +} + + +/* incoming characters */ + +ISR(USART0_RX_vect) +{ + uint8_t in, err; + + err = UCSR0A & ((1 << FE0) | (1 << UPE0)); // check error + in = UDR0; // get the byte + + if (err) // reject error + return; + + if ((flow & FLOW_SW) == FLOW_XONOFF) + { + // XON, XOFF received, update status + if ((in == XON) || (in == XOFF)) + { + remote_xonoff = in; + return; + } + } + + // reject byte if DTE didn't assert RTS + // (only effective if we're DCE in RTS/CTS mode) + if (!income_requested()) + return; + + // accept byte + add_income(in, 0); +} + +void add_income ( + const uint8_t in, + const uint8_t blocking +) +{ + while (FULL_BP(income_w, income_r, N_INCOME_BUFFER)) // no place in buffer + { + if (blocking) // we must wait + handle_income(); // perform input handling to free space in buffer + else // we cannot wait, input is lost! + { + set_led = 10; + set_alarm = 1; + reject_income(); + return; + } + } + + set_led = 2; // show that something is happening + + income_buffer[income_w] = in; + ADVANCE_BP(income_w, N_INCOME_BUFFER); + + if (DIFF_BP(income_w, income_r, N_INCOME_BUFFER) >= INCOME_BUFFER_HIGH) + { + // buffer getting full, don't accept new input (flow control) + reject_income(); + } + + // can't go to sleep when there is unhandled data in buffer + cancel_sleep(WAKEUP_INCOME); +} + +void add_income_str ( + uint8_t const * in, + const uint8_t blocking +) +{ + uint8_t const * p; + + for (p = in; *p != 0x00; ++p) + add_income(*p, blocking); +} + +void add_income_dec ( + const uint32_t value, + const uint8_t min_digits, + const uint8_t blocking +) +{ + uint8_t text[11]; + uint8_t x; + + x = make_dec_string( + text, + value, + min_digits, + 10 + ); + text[x] = 0x00; + add_income_str(text, blocking); +} + +void add_income_hex ( + const uint32_t value, + const uint8_t min_digits, + const uint8_t blocking +) +{ + uint8_t text[9]; + uint8_t x; + + x = make_hex_string( + text, + value, + min_digits, + 8, + 1 + ); + text[x] = 0x00; + add_income_str(text, blocking); +} + +void handle_income (void) +{ + uint8_t in; + + static uint8_t uni_bytes = 0; + static uint32_t uni_ch = 0; + + uint8_t uni_ctrl; + + // wait until next page is inserted + if (wait_page) + { + if (paper == PAPER_CONTINUOUS) + wait_page = 0; + else + { + set_led = 2; + return; + } + } + + cli(); + if (EMPTY_BP(income_w, income_r, N_BUFER_INCOME)) + { + sei(); + // nothing left in buffer + if (mode & MODE_HEX) + handle_hex(HEX_NOTHING, 0); + + accept_income(); // allow remote machine to send data (flow control) + allow_sleep(WAKEUP_INCOME); + } + else + { + sei(); + + in = income_buffer[income_r]; + ADVANCE_BP(income_r, N_INCOME_BUFFER); + + if (DIFF_BP(income_w, income_r, N_INCOME_BUFFER) < INCOME_BUFFER_LOW) // buffer getting free + accept_income(); // allow remote machine to send data (flow control) + + // first event was received data; goto terminal mode + if (mode == MODE_WAIT) + become_terminal(); + + if (mode & MODE_TERM) // only if we are in terminal mode + { + if (mode & MODE_HEX) // HEX + handle_hex(HEX_AVAILABLE, in); + else if (encoding & ENC_UNI) // UTF-8 + { + if ((in & 0b11000000) == 0b10000000) // continuation of sequence + { + if (uni_bytes) // byte was expected. handle it + { + uni_ch <<= 6; + uni_ch |= in & 0b00111111; + --uni_bytes; + if (!uni_bytes) // finished + { + /* nothing else to do here */ + } + } + else // unexpected continuation byte + uni_ch = -1; + } + else // new + { + if (uni_bytes) // continuation was expected + { + handle_ctrl(0xFF); + add_print_ch(CH_UNKN); + } + if ((in & 0b10000000) == 0b00000000) // 1 byte + { + uni_ch = in; + uni_bytes = 0; + } + else if ((in & 0b11100000) == 0b11000000) // 2 byte + { + uni_ch = in & 0b00011111; + uni_bytes = 1; + } + else if ((in & 0b11110000) == 0b11100000) // 3 byte + { + uni_ch = in & 0b00001111; + uni_bytes = 2; + } + else if ((in & 0b11111000) == 0b11110000) // 4 byte + { + uni_ch = in & 0b00000111; + uni_bytes = 3; + } + else if ((in & 0b11111100) == 0b11111000) // 5 byte [???] + { + uni_ch = in & 0b00000011; + uni_bytes = 4; + } + else if ((in & 0b11111110) == 0b11111100) // 6 byte [???] + { + uni_ch = in & 0b00000001; + uni_bytes = 5; + } + else if (in == 0b11111110) // 7 byte [???] + { + uni_ch = 0; + uni_bytes = 6; + } + else // ??? + { + uni_ch = -1; + uni_bytes = 0; + } + } + + if (!uni_bytes) // no unfinished sequence + { + if (uni_ch < 0x100) + uni_ctrl = uni_ch; + else + uni_ctrl = 0xFF; + + if (handle_ctrl(uni_ctrl)) // check if control char / function / sequence + { + } + else // no; normal character to print + { + add_print_ch_UNI(uni_ch); + // if (uni_ch < CH_LIMIT) + // add_print_ch(UNI_TABLE[uni_ch]); + // else + // add_print_ch(CH_UNKN); + } + } + } + else // 8 bit encoding + { + if (uni_bytes) + { + uni_bytes = 0; + handle_ctrl(0xFF); + add_print_ch(CH_UNKN); + } + if (handle_ctrl(in)) // check if control char / function / sequence + { + } + else // no; normal character to print + { + add_print_ch_CP(in); + // if (in & 0b10000000) + // add_print_ch(CH_CP[in]); + // else + // add_print_ch(CH_ASCII[in]); + } + } + } + } +} + + +/* hex */ + +void handle_hex ( + const uint8_t cmd, + const uint8_t value +) +{ + static int16_t r_lmargin = 0; + static int16_t r_rmargin = 0; + static uint8_t r_cwidth = 0; + static uint8_t columns = 0; + uint8_t new_columns; + + static uint8_t buffer[16]; + static uint8_t rl = 0; + static uint8_t rr = 0; + static uint8_t wr = 0; + static uint8_t side = 0; + static uint8_t rel = 0; + + static uint16_t address = 0x0000; + + uint8_t force_output = 0; + uint8_t write_later = 0; + + if (cmd & HEX_RESET) + { + address = 0x0000; + rl = 0; + rr = 0; + wr = 0; + side = 0; + force_output = 1; + if (hpos_aim != lmargin_aim) + { + goto_lmargin(); + goto_next_line(0); + } + } + if (cmd & (HEX_FORCE | HEX_FINISH)) + force_output = 1; + if ( + (!(cmd & HEX_AVAILABLE)) && + (((int32_t)(main_timer - last_print_time)) >= (119 * TIME_10MS)) + ) + force_output = 1; + + if ( + (lmargin_aim != r_lmargin) || + (rmargin_aim != r_rmargin) || + (cwidth_aim != r_cwidth) + ) + { + r_lmargin = lmargin_aim; + r_rmargin = rmargin_aim; + r_cwidth = cwidth_aim; + +/* +0001 00 0 +0002 00 11 01 +0004 00 11 22 33 0123 +0008 00 11 22 33 44 55 55 77 01234567 +0010 00 11 22 33 44 55 66 77 88 88 AA BB CC DD EE FF 0123456789ABCDEF +*/ + + if ((r_rmargin - r_lmargin) >= (r_cwidth * (uint16_t)70)) + { + new_columns = 16; + rel = 54; + } + else if ((r_rmargin - r_lmargin) >= (r_cwidth * (uint16_t)38)) + { + new_columns = 8; + rel = 30; + } + else if ((r_rmargin - r_lmargin) >= (r_cwidth * (uint16_t)22)) + { + new_columns = 4; + rel = 18; + } + else if ((r_rmargin - r_lmargin) >= (r_cwidth * (uint16_t)14)) + { + new_columns = 2; + rel = 12; + } + else if ((r_rmargin - r_lmargin) >= (r_cwidth * (uint16_t)10)) + { + new_columns = 1; + rel = 9; + } + else + { + new_columns = 0; + rel = 0; + } + + if (new_columns != columns) + force_output = 1; + } + else + new_columns = columns; + + if (cmd & HEX_AVAILABLE) + { + if (wr < columns) // will fit in line + { + buffer[wr] = value; + ++wr; + } + else + write_later = 1; + } + + if (wr >= columns) + force_output = 1; + + if (columns) + { + while ((rl < wr) || (rr < wr)) + { + if (!side) // left part + { + if (rl= 0x20) && (buffer[rr] <= 0x7E)) + add_print_ch_ASCII(buffer[rr]); + else + add_print_ch_ASCII('.'); + ++rr; + } + else // out of available data + { + if (force_output) + side = 0; + else + break; + } + } + } + if( + (rl >= columns) && + (rr >= columns) && + (rl >= wr) && + (rr >= wr) + ) + { + address += wr; + wr = 0; + rl = 0; + rr = 0; + side = 0; + goto_lmargin(); + goto_next_line(0); + } + } + else + { + for(rr=0; rr= 0x40) && (in <= 0x5F)) // C1 recode + { + in += 0x40; + c1_allowed = 1; // even if originally unavailable, escape makes it possible + if (ind) // overwrite the ESC + --ind; + } + else // delayed reaction; interrupt previous sequence, start new + { + if (buffer[0] != 0x98) // SOS can contain ESC + { + buffer[0] = 0x1B; + ib = 0; + ind = 1; + } + } + } + + // C0, C1, GR not allowed inside sequences unless in control string + if ( + ((in < 0x20) || (in > 0x7E)) && // char out of GL + (in != 0x1B) && // but not ESC (deal with it in next iteration) + ind // in sequence already + ) + { + switch(buffer[0]) + { + case 0x98: // SOS + break; + case 0x90: // DCS + case 0x9A: // SCI + case 0x9D: // OSC + case 0x9E: // PM + case 0x9F: // APC + if (((in >= 0x08) && (in <= 0x0C)) || (in == 0x9C)) // allowed; do nothing + break; + default: + ind = 0; + break; + } + } + } + + if (ind < N_ESC_BUFFER) + buffer[ind] = in; + + if (!ind) // single character or new sequence + { + if ((in <= 0x1F) || (in == 0x7F)) // C0 + { + handled = 1; + switch (in) + { + case 0x00: // NUL - NULL + break; + // case 0x01: // SOH - START OF HEADING + // case 0x02: // STX - START OF TEXT + // case 0x03: // ETX - END OF TEXT + // case 0x04: // EOT - END OF TRANSMISSION + // case 0x05: // ENQ - ENQUIRY + // case 0x06: // ACK - ACKNOWLEDGE + case 0x07: // BEL - BELL + add_print_key (CODE_BELL); + break; + case 0x08: // BS - BACKSPACE + case 0x7F: // DEL - DELETE // TODO: should I accept this here? + goto_prev_col(0); + break; + case 0x09: // HT - CHARACTER TABULATION + goto_next_htab(0); + break; + case 0x0A: // LF - LINE FEED + if (nl_mode & NL_IMPLICIT_CR) + goto_lmargin(); + if (!((nl_mode & NL_IMPLICIT_LF) && (prev==0x0D))) // already handled in last step? + goto_next_line(0); + break; + case 0x0B: // VT - LINE TABULATION + goto_next_vtab(0); + break; + case 0x0C: // FF - FORM FEED + goto_next_page_tmargin(); + break; + case 0x0D: // CR - CARRIAGE RETURN + goto_lmargin(); + if (nl_mode & NL_IMPLICIT_LF) + goto_next_line(0); + break; + // case 0x0E: // SO - SHIFT-OUT + // case 0x0F: // SI - SHIFT-IN + // case 0x10: // DLE - DATA LINK ESCAPE + // case 0x11: // DC1 - DEVICE CONTROL ONE + // case 0x12: // DC2 - DEVICE CONTROL TWO + // case 0x13: // DC3 - DEVICE CONTROL THREE + // case 0x14: // DC4 - DEVICE CONTROL FOUR + // case 0x15: // NAK - NEGATIVE ACKNOWLEDGE + // case 0x16: // SYN - SYNCHRONOUS IDLE + // case 0x17: // ETB - END OF TRANSMISSION BLOCK + // case 0x18: // CAN - CANCEL + // case 0x19: // EM - END OF MEDIUM + // case 0x1A: // SUB - SUBSTITUTE + case 0x1B: // ESC - ESCAPE + if (esc_mode == ESC_ECMA_48) + { + ++ind; // start sequence + ib = 0; // reset intermediate byte count + } + // else if (esc_mode == ESC_P_POS) + // ++ind; + break; + // case 0x1C: // IS4 - INFORMATION SEPARATOR FOUR + // case 0x1D: // IS3 - INFORMATION SEPARATOR THREE + // case 0x1E: // IS2 - INFORMATION SEPARATOR TWO + // case 0x1F: // IS1 - INFORMATION SEPARATOR ONE + default: + if (esc_mode == ESC_NONE) + { + add_print_ch(CH_ASCII['^']); + add_print_ch(CH_ASCII['@'+in]); + } + break; + } + } + else if ((in >= 0x80) && (in <= 0x9F) && c1_allowed) // C1 + { + if (esc_mode == ESC_ECMA_48) + { + handled = 1; + switch (in) + { + //case 0x80: // 1B 40 reserved + //case 0x81: // 1B 41 reserved + //case 0x82: // 1B 42 BPH - BREAK PERMITTED HERE + //case 0x83: // 1B 43 NBH - NO BREAK HERE + //case 0x84: // 1B 44 reserved + case 0x85: // 1B 45 NEL - NEXT LINE + goto_lmargin(); + goto_next_line(0); + break; + //case 0x86: // 1B 46 SSA - START OF SELECTED AREA + //case 0x87: // 1B 47 ESA - END OF SELECTED AREA + case 0x88: // 1B 48 HTS - CHARACTER TABULATION SET + set_htab(hpos_aim); + break; + case 0x89: // 1B 49 HTJ - CHARACTER TABULATION WITH JUSTIFICATION + goto_next_htab(0); + break; + case 0x8A: // 1B 4A VTS - LINE TABULATION SET + set_vtab(vpos_aim); + break; + case 0x8B: // 1B 4B PLD - PARTIAL LINE FORWARD + goto_next_vstep(); + break; + case 0x8C: // 1B 4C PLU - PARTIAL LINE BACKWARD + goto_prev_vstep(); + break; + case 0x8D: // 1B 4D RI - REVERSE LINE FEED + goto_prev_line(0); + break; + //case 0x8E: // 1B 4E SS2 - SINGLE-SHIFT TWO + //case 0x8F: // 1B 4F SS3 - SINGLE-SHIFT THREE + //case 0x91: // 1B 51 PU1 - PRIVATE USE ONE + //case 0x92: // 1B 52 PU2 - PRIVATE USE TWO + //case 0x93: // 1B 53 STS - SET TRANSMIT STATE + //case 0x94: // 1B 54 CCH - CANCEL CHARACTER + case 0x95: // 1B 55 MW - MESSAGE WAITING + send_DSR_ok(); + break; + //case 0x96: // 1B 56 SPA - START OF GUARDED AREA + //case 0x97: // 1B 57 EPA - END OF GUARDED AREA + //case 0x99: // 1B 59 reserved + //case 0x9C: // 1B 5C ST - STRING TERMINATOR + + // control string / control sequence: + + case 0x90: // 1B 50 DCS 08-0C,20-7E - DEVICE CONTROL STRING + case 0x98: // 1B 58 SOS any - START OF STRING + case 0x9A: // 1B 5A SCI 08-0C,20-7E - SINGLE CHARACTER INTRODUCER + case 0x9D: // 1B 5D OSC 08-0C,20-7E - OPERATING SYSTEM COMMAND + case 0x9E: // 1B 5E PM 08-0C,20-7E - PRIVACY MESSAGE + case 0x9F: // 1B 5F APC 08-0C,20-7E - APPLICATION PROGRAM COMMAND + case 0x9B: // 1B 5B CSI - CONTROL SEQUENCE INTRODUCER + ++ind; + ib = 0; + break; + } + + } + else + handled = 0; + } + else // normal text + handled = 0; + } + else // continued sequence + { + if (esc_mode == ESC_ECMA_48) + { + handled = 1; + + if (in == 0x1B) // ESC - ESCAPE + { + // allow to go through. We'll deal with it next iteration. + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else + { + switch (buffer[0]) + { + case 0x1B: // ESC - ESCAPE + if ((buffer[1] >= 0x20) && (buffer[1] <= 0x2F)) // nF + { + if ((in >= 0x20) && (in <= 0x2F)) // intermediate byte + { + ++ib; // count intermediate bytes + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else if ((in >= 0x30) && (in <= 0x7E)) // final byte + { + switch (buffer[1]) + { + // case 0x20: // ANNOUNCE CODE STRUCTURE + // case 0x21: // C0-DESIGNATE + // case 0x22: // C1-DESIGNATE + // case 0x23: // Single control functions + // case 0x24: // Designation of multiple-byte graphic character sets + case 0x25: // DESIGNATE OTHER CODING SYSTEM + if (ib == 1) // single intermediate byte + long_id = buffer[2]; + else if (ib == 2) // 2 intermediate bytes + long_id = (((uint16_t)buffer[2])<<8) | buffer[3]; + else // invalid + break; + switch (long_id) + { + case 0x47: // goto UTF-8 + case 0x2f47: + case 0x2f48: + case 0x2f49: + set_encoding(encoding | ENC_UNI); + break; + case 0x40: // return to ECMA-35 + set_encoding_GR(GR_index); + break; + } + break; + // case 0x26: // IDENTIFY REVISED REGISTRATION + // case 0x27: // (reserved for future standardisation) + // case 0x28: // G0-DESIGNATE 94-SET + // case 0x29: // G1-DESIGNATE 94-SET + // case 0x2A: // G2-DESIGNATE 94-SET + // case 0x2B: // G3-DESIGNATE 94-SET + // case 0x2C: // (reserved for future standardisation) + case 0x2D: // G1-DESIGNATE 96-SET + case 0x2E: // G2-DESIGNATE 96-SET + case 0x2F: // G3-DESIGNATE 96-SET + u0 = buffer[1] - 0x2D + 1; + if (ib == 1) // single intermediate byte + { + switch (buffer[2]) // final byte + { + case 0x41: + case 0x63: + GR_table[u0] = ENC_ISO8859_1; + break; + case 0x42: + GR_table[u0] = ENC_ISO8859_2; + break; + case 0x43: + GR_table[u0] = ENC_ISO8859_3; + break; + case 0x44: + case 0x64: + GR_table[u0] = ENC_ISO8859_4; + break; + case 0x4D: + GR_table[u0] = ENC_ISO8859_9; + break; + case 0x56: + GR_table[u0] = ENC_ISO8859_10; + break; + case 0x65: + GR_table[u0] = ENC_ISO8859_13; + break; + case 0x62: + GR_table[u0] = ENC_ISO8859_15; + break; + default: + u0 = 0xff; + } + if (u0 == GR_index) // reassigned already selected encoding; update + set_encoding_GR(GR_index); + } + break; + } + ind = 0; + } + else // invalid value + { + ind = 0; + handled = 0; + } + } + else if ((buffer[1] >= 0x30) && (buffer[1] <= 0x7E)) // Fp, Fs, control function + { + switch(buffer[1]) + { + // case 0x60: // DMI - DISABLE MANUAL INPUT + // case 0x61: // INT - INTERRUPT + // case 0x62: // EMI - ENABLE MANUAL INPUT + case 0x63: // RIS - RESET TO INITIAL STATE + out_margin = 0; + + pheight = DEFAULT_PHEIGHT; + tmargin = DEFAULT_TMARGIN; + bmargin = DEFAULT_BMARGIN; + lheight = HEIGHT_NORMAL; + theight_ch = DEFAULT_THEIGHT_CH; + + lwidth = DEFAULT_LWIDTH; + lmargin_aim = DEFAULT_LMARGIN_AIM; + rmargin_aim = DEFAULT_RMARGIN_AIM; + cwidth_aim = WIDTH_NORMAL; + cwidth_todo = 1; + twidth_ch = DEFAULT_TWIDTH_CH; + + set_style_normal(); + + load_config(); + + ppos = -1; + vpos_aim = pheight + tmargin; + hpos_aim = lmargin_aim; + adjust_print_pos(); + break; + // case 0x64: // CMD - CODING METHOD DELIMITER + // case 0x6E: // LS2 - LOCKING-SHIFT TWO + // case 0x6F: // LS3 - LOCKING-SHIFT THREE + case 0x7C: // LS3R - LOCKING-SHIFT THREE RIGHT + set_encoding_GR(3); + break; + case 0x7D: // LS2R - LOCKING-SHIFT TWO RIGHT + set_encoding_GR(2); + break; + case 0x7E: // LS1R - LOCKING-SHIFT ONE RIGHT + set_encoding_GR(1); + break; + default: + break; + } + ind = 0; + } + else // invalid value + { + ind = 0; + handled = 0; + } + break; + case 0x9B: // 1B 5B CSI - CONTROL SEQUENCE INTRODUCER + if ((in >= 0x30) && (in <= 0x3F)) // parameter byte + { + if (prev < 0x30) // I before P + { + ind = 0; + handled = 0; + } + else // ok + { + if (ind < N_ESC_BUFFER-1) + ++ind; + } + } + else if ((in >= 0x20) && (in <= 0x2F)) // intermediate byte + { + ++ib; // count intermediate bytes + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else if ((in >= 0x40) && (in <= 0x7E)) // final byte + { + buffer_pos = buffer + 1; + if (ib == 0) // just 1 final byte + long_id = in; + else if (ib == 1) // 1 intermediate & 1 final byte + long_id = (((uint16_t)prev)<<8)|in; + else // invalid + long_id =0; + switch (long_id) + { + // case 0x40: // ICH - INSERT CHARACTER + case 0x41: // CUU - CURSOR UP + case 0x6B: // VPB - LINE POSITION BACKWARD + move_back_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x42: // CUD - CURSOR DOWN + case 0x65: // VPR - LINE POSITION FORWARD + move_forward_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x43: // CUF - CURSOR RIGHT + case 0x61: // HPR - CHARACTER POSITION FORWARD + move_forward_col((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x44: // CUB - CURSOR LEFT + case 0x6A: // HPB - CHARACTER POSITION BACKWARD + move_back_col((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x45: // CNL - CURSOR NEXT LINE + goto_col0(); + move_forward_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x46: // CPL - CURSOR PRECEDING LINE + goto_col0(); + move_back_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x47: // CHA - CURSOR CHARACTER ABSOLUTE + case 0x60: // HPA - CHARACTER POSITION ABSOLUTE + goto_col(((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1))-1); + break; + case 0x48: // CUP - CURSOR POSITION + case 0x66: // HVP - CHARACTER AND LINE POSITION + goto_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + goto_col((uint8_t)get_ctrl_parameter(CTRL_IND, 1, 0, 1)-1); + break; + case 0x49: // CHT - CURSOR FORWARD TABULATION + move_forward_htab ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x4A: // ED - ERASE IN PAGE + // case 0x4B: // EL - ERASE IN LINE + // case 0x4C: // IL - INSERT LINE + // case 0x4D: // DL - DELETE LINE + // case 0x4E: // EF - ERASE IN FIELD + // case 0x4F: // EA - ERASE IN AREA + // case 0x50: // DCH - DELETE CHARACTER + // case 0x51: // SEE - SELECT EDITING EXTENT + // case 0x52: // CPR - ACTIVE POSITION REPORT + // case 0x53: // SU - SCROLL UP + // case 0x54: // SD - SCROLL DOWN + case 0x55: // NP - NEXT PAGE + move_forward_page_tmargin((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x56: // PP - PRECEDING PAGE + move_back_page_tmargin((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x57: // CTC - CURSOR TABULATION CONTROL + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + set_htab(hpos_aim); + break; + case 1: + set_vtab(vpos_aim); + break; + case 2: + clear_htab(hpos_aim); + break; + case 3: + clear_vtab(hpos_aim); + break; + case 4: + case 5: + clear_htab_all(); + break; + case 6: + clear_vtab_all(); + break; + } + break; + // case 0x58: // ECH - ERASE CHARACTER + case 0x59: // CVT - CURSOR LINE TABULATION + move_forward_vtab((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x5A: // CBT - CURSOR BACKWARD TABULATION + move_back_htab ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x5B: // SRS - START REVERSED STRING + // case 0x5C: // PTX - PARALLEL TEXTS + // case 0x5D: // SDS - START DIRECTED STRING + // case 0x5E: // SIMD - SELECT IMPLICIT MOVEMENT DIRECTION + // case 0x62: // REP - REPEAT // TODO:??? + // case 0x63: // DA - DEVICE ATTRIBUTES + case 0x64: // VPA - LINE POSITION ABSOLUTE + goto_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x67: // TBC - TABULATION CLEAR + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + clear_htab(hpos_aim); + break; + case 1: + clear_vtab(vpos_aim); + break; + case 2: + case 3: + clear_htab_all(); + break; + case 5: + clear_htab_all(); + case 4: + clear_vtab_all(); + break; + } + break; + // case 0x68: // SM - SET MODE + // case 0x69: // MC - MEDIA COPY + // case 0x6C: // RM - RESET MODE + case 0x6D: // SGR - SELECT GRAPHIC RENDITION + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + case 65: + set_style_normal(); + break; + case 1: + set_style_bold(); + break; + case 4: + set_style_under(); + break; + case 9: + set_style_cross(); + break; + case 21: + set_style_under2(); + break; + case 22: + set_style_nobold(); + break; + case 24: + set_style_nounder(); + break; + case 29: + set_style_nocross(); + break; + case 53: + set_style_over(); + break; + case 55: + set_style_noover(); + break; + } + break; + case 0x6E: // DSR - DEVICE STATUS REPORT + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + //case 0: + //case 1: + //case 2: + //case 3: + //case 4: + case 5: + send_DSR_ok(); + break; + case 6: + send_CPR(); + break; + } + break; + // case 0x6F: // DAQ - DEFINE AREA QUALIFICATION + + // case 0x2040: // SL - SCROLL LEFT + // case 0x2041: // SR - SCROLL RIGHT + // case 0x2043: // GSS - GRAPHIC SIZE SELECTION + // set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + // // width is implicit, but I don't change it here + // break; + // case 0x2044: // FNT - FONT SELECTION + // case 0x2045: // TSS - THIN SPACE SPECIFICATION + // case 0x2046: // JFY - JUSTIFY + case 0x2047: // SPI - SPACING INCREMENT + set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + set_cwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 1, 0, 0))); + break; + // case 0x2048: // QUAD - QUAD + case 0x2049: // SSU - SELECT SIZE UNIT + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: // CHARACTER + hunit_mul = HUNIT_MUL_CH; + hunit_div = HUNIT_DIV_CH; + vunit_mul = VUNIT_MUL_CH; + vunit_div = VUNIT_DIV_CH; + break; + case 1: // MILLIMETRE + hunit_mul = HUNIT_MUL_MM; + hunit_div = HUNIT_DIV_MM; + vunit_mul = VUNIT_MUL_MM; + vunit_div = VUNIT_DIV_MM; + break; + case 2: // COMPUTER DECIPOINT + hunit_mul = HUNIT_MUL_CDP; + hunit_div = HUNIT_DIV_CDP; + vunit_mul = VUNIT_MUL_CDP; + vunit_div = VUNIT_DIV_CDP; + break; + case 3: // DECIDIDOT + hunit_mul = HUNIT_MUL_DD; + hunit_div = HUNIT_DIV_DD; + vunit_mul = VUNIT_MUL_DD; + vunit_div = VUNIT_DIV_DD; + break; + case 4: // MIL + hunit_mul = HUNIT_MUL_MIL; + hunit_div = HUNIT_DIV_MIL; + vunit_mul = VUNIT_MUL_MIL; + vunit_div = VUNIT_DIV_MIL; + break; + case 5: // BASIC MEASURING UNIT + hunit_mul = HUNIT_MUL_BMU; + hunit_div = HUNIT_DIV_BMU; + vunit_mul = VUNIT_MUL_BMU; + vunit_div = VUNIT_DIV_BMU; + break; + case 6: // MICROMETRE + hunit_mul = HUNIT_MUL_UM; + hunit_div = HUNIT_DIV_UM; + vunit_mul = VUNIT_MUL_UM; + vunit_div = VUNIT_DIV_UM; + break; + case 7: // PIXEL + hunit_mul = 1; + hunit_div = 1; + vunit_mul = 1; + vunit_div = 1; + break; + case 8: // DECIPOINT + hunit_mul = HUNIT_MUL_DP; + hunit_div = HUNIT_DIV_DP; + vunit_mul = VUNIT_MUL_DP; + vunit_div = VUNIT_DIV_DP; + break; + } + break; + case 0x204A: // PFS - PAGE FORMAT SELECTION + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_PF) + { + set_pheight(PHEIGHT_PRESET[u0]); + set_tmargin(0); + set_bmargin_rel(0); + set_theight_ch(theight_ch); + set_lwidth(LWIDTH_PRESET[u0]); + set_lmargin(LMARGIN_PRESET); + set_rmargin_rel(0-RMARGIN_PRESET); + set_twidth_ch(twidth_ch); + adjust_print_pos(); + // TODO: new page? + } + break; + case 0x204B: // SHS - SELECT CHARACTER SPACING + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_CWIDTH) + set_cwidth(CWIDTH_PRESET[u0]); + break; + case 0x204C: // SVS - SELECT LINE SPACING + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_LHEIGHT) + set_lheight(LHEIGHT_PRESET[u0]); + break; + // case 0x204D: // IGS - IDENTIFY GRAPHIC SUBREPERTOIRE + // case 0x204F: // IDCS - IDENTIFY DEVICE CONTROL STRING + case 0x2050: // PPA - PAGE POSITION ABSOLUTE + goto_page((int16_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x2051: // PPR - PAGE POSITION FORWARD + move_forward_page((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x2052: // PPB - PAGE POSITION BACKWARD + move_back_page((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + // case 0x2053: // SPD - SELECT PRESENTATION DIRECTIONS + case 0x2054: // DTA - DIMENSION TEXT AREA + set_pheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + set_lwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 1, 0, 0))); + adjust_print_pos(); + // TODO: set new margins? + break; + case 0x2055: // SLH - SET LINE HOME + set_lmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x2056: // SLL - SET LINE LIMIT + set_rmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + // case 0x2057: // FNK - FUNCTION KEY + // case 0x2058: // SPQR - SELECT PRINT QUALITY AND RAPIDITY + case 0x2059: // SEF - SHEET EJECT AND FEED + // partial implementation: move out of page + goto_next_page_tmargin(); + break; + case 0x205A: // PEC - PRESENTATION EXPAND OR CONTRACT + switch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + set_cwidth(WIDTH_NORMAL); + break; + case 1: + set_cwidth(WIDTH_WIDE); + break; + case 2: + set_cwidth(WIDTH_NARROW); + break; + } + break; + // case 0x205B: // SSW - SET SPACE WIDTH + // case 0x205C: // SACS - SET ADDITIONAL CHARACTER SEPARATION + // case 0x205D: // SAPV - SELECT ALTERNATIVE PRESENTATION VARIANTS + case 0x205E: // STAB - SELECTIVE TABULATION + // arbitrary choice + goto_htab((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x205F: // GCC - GRAPHIC CHARACTER COMBINATION + // case 0x2060: // TATE - TABULATION ALIGNED TRAILING EDGE + // case 0x2061: // TALE - TABULATION ALIGNED LEADING EDGE + // case 0x2062: // TAC - TABULATION ALIGNED CENTRED + // case 0x2063: // TAC - TABULATION ALIGNED CENTRED + case 0x2064: // TSR - TABULATION STOP REMOVE + clear_htab_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + // case 0x2065: // SCO - SELECT CHARACTER ORIENTATION + // case 0x2066: // SRCS - SET REDUCED CHARACTER SEPARATION + case 0x2067: // SCS - SET CHARACTER SPACING + set_cwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + break; + case 0x2068: // SLS - SET LINE SPACING + set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + break; + case 0x2069: // SPH - SET PAGE HOME + set_tmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x206A: // SPL - SET PAGE LIMIT + set_bmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)); + break; + // case 0x206B: // SCP - SELECT CHARACTER PATH + } + ind = 0; + } + else // invalid value + { + ind = 0; + handled = 0; + } + break; + case 0x90: // 1B 50 DCS - DEVICE CONTROL STRING + case 0x98: // 1B 58 SOS - START OF STRING + case 0x9A: // 1B 5A SCI - SINGLE CHARACTER INTRODUCER + case 0x9D: // 1B 5D OSC - OPERATING SYSTEM COMMAND + case 0x9E: // 1B 5E PM - PRIVACY MESSAGE + case 0x9F: // 1B 5F APC - APPLICATION PROGRAM COMMAND + if (in == 0x9C) // 1B 5C ST - STRING TERMINATOR + { + /* control string would be handled here if implemented */ + ind = 0; + } + else if (ind < N_ESC_BUFFER-1) + ++ind; + break; + default: + // how did we get here? + ind = 0; + handled = 0; + } + } + } + else + { + ind = 0; + handled = 0; + } + } + prev = in; + return handled; +} + +uint32_t get_ctrl_parameter ( + uint8_t * buffer, + uint8_t * * pos, + uint8_t * ind, + uint8_t * subind, + uint8_t id, + uint8_t subid, + uint32_t def +) +{ + uint32_t val = 0; + uint8_t ch; + uint8_t return_now = 0; + uint8_t return_default = 1; + + // too far, move to start. + if ((id < *ind) || ((id == *ind) && (subid < *subind))) + { + *pos = buffer; + *ind = 0; + *subind = 0; + } + + if (*pos == buffer) // at start + { + if ((*buffer < 0x30) || (*buffer > 0x3B)) // not a parameter string + { + return def; + } + } + + while (1) + { + ch = **pos; + switch (ch) + { + case 0x30: // digit + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + if ((*ind == id) && (*subind == subid)) + { + return_default = 0; + val *= 10; + val += ch - 0x30; + } + ++(*pos); + break; + case 0x3A: // : substring separator + if ((*ind == id) && (*subind == subid)) + { + return_now = 1; + } + ++(*subind); + ++(*pos); + break; + case 0x3B: // ; string separator + if ((*ind == id) && (*subind == subid)) + { + return_now = 1; + } + ++(*ind); + *subind = 0; + ++(*pos); + break; + default: // end of parameter strings + return_now = 1; + } + + if (return_now) + { + return return_default ? def : val; + } + } +} + +static inline void send_DSR_ok (void) +{ + add_outcome_str((uint8_t *)"\x1B\x5B\x30\x6E"); +} + +static inline void send_CPR (void) +{ + add_outcome(0x1B); // ESC + add_outcome(0x5B); // CSI + add_outcome_dec((vpos_aim/lheight)+1, 1); // Pn1 - line number + add_outcome(0x3B); // separator + add_outcome_dec((hpos_aim/cwidth_aim)+1, 1); // Pn2 - column number + add_outcome(0x52); // CPR - ACTIVE POSITION REPORT +} + + +/* outcoming characters */ + +void add_outcome (const uint8_t out) +{ + if ( + (out & 0x80) && // high bit set + ((serial_mode & UART_DATA) == UART_DATA_7) // serial set to 7 bits + ) + return; // refuse to send such value in this mode + + while (FULL_BP(outcome_w, outcome_r, N_OUTCOME_BUFFER)) // buffer is full + { + // try handling the outcoming data to make some place + handle_outcome(); + } + + outcome_buffer[outcome_w] = out; + ADVANCE_BP(outcome_w, N_OUTCOME_BUFFER); + + // cannot sleep when there are bytes to send out + cancel_sleep(WAKEUP_OUTCOME); +} + +void add_outcome_str (uint8_t const * out) +{ + uint8_t const * p; + + for (p = out; *p != 0x00; ++p) + add_outcome(*p); +} + +void add_outcome_dec ( + const uint32_t value, + const uint8_t min_digits +) +{ + uint8_t text[11]; + uint8_t x; + + x = make_dec_string( + text, + value, + min_digits, + 10 + ); + text[x] = 0x00; + add_outcome_str(text); +} + +void add_outcome_hex ( + const uint32_t value, + const uint8_t min_digits +) +{ + uint8_t text[9]; + uint8_t x; + + x = make_hex_string( + text, + value, + min_digits, + 8, + 1 + ); + text[x] = 0x00; + add_outcome_str(text); +} + +void handle_outcome (void) +{ + if (send_xonoff) // requested to send XON or XOFF + { + if (UCSR0A & (1< 0) + { + if (diff > 255) // sorry, too far + return; + move_forward_page(diff); + } + else if (diff < 0) + { + if (diff < -255) // sorry, too far + return; + move_back_page(0-diff); + } +} + + +uint8_t goto_prev_line (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + vpos_aim -= lheight; + + if ((vpos_aim < tmargin ) && (!out_margin))// don't apply -1 offset + { + stop = 1; + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + else if (vpos_aim < 0) + { + stop = 1; + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + + adjust_print_pos(); + return stop; +} + +uint8_t goto_next_line (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + vpos_aim += lheight; + + if (((vpos_aim + lheight) > bmargin ) && (!out_margin)) // don't apply +1 offset + { + stop = 1; + } + else if ((vpos_aim + lheight) > pheight) // don't apply +1 offset + { + stop = 1; + } + + adjust_print_pos(); + return stop; +} + +void move_back_line ( + const uint8_t n, + const uint8_t ignore_margin +) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i pheight) // don't apply +1 offset + { + if(vpos <= (pheight - lheight)) + vpos_aim = pheight - lheight; + else + vpos_aim = vpos; + } + adjust_print_pos(); +} + +void goto_line_rel (uint8_t y) +{ + if (y == 0xff) //-1 + y = 0; + + vpos_aim = tmargin + y * lheight; + + if ((vpos_aim + lheight) > bmargin) // don't apply +1 offset + { + if(vpos <= (bmargin - lheight)) + vpos_aim = bmargin - lheight; + else + vpos_aim = vpos; + } + adjust_print_pos(); +} + +static inline void goto_prev_vstep (void) +{ + --vpos_aim; + adjust_print_pos(); +} + +static inline void goto_next_vstep (void) +{ + ++vpos_aim; + adjust_print_pos(); +} + + +uint8_t goto_prev_col (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + hpos_aim -= cwidth_aim; + + if ((hpos_aim < lmargin_aim) && (!out_margin)) + { + hpos_aim = lmargin_aim; + stop = 1; + } + else if (hpos_aim < 0) + { + hpos_aim = 0; + stop = 1; + } + + adjust_print_pos(); + return stop; +} + +uint8_t goto_next_col (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + hpos_aim += cwidth_aim; + + if (((hpos_aim + cwidth_aim) > rmargin_aim) && (!out_margin)) + { + stop = 1; + } + else if ((hpos_aim + cwidth_aim) > lwidth) + { + stop = 1; + } + + adjust_print_pos(); + return stop; +} + +void move_back_col ( + const uint8_t n, + const uint8_t ignore_margin +) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i lwidth) + hpos_aim = lwidth - cwidth_aim; + adjust_print_pos(); +} + +void goto_col_rel (uint8_t x) +{ + if (x == 0xff) //-1 + x = 0; + + hpos_aim = lmargin_aim + x * cwidth_aim; + + if ((hpos_aim + cwidth_aim) > rmargin_aim) + hpos_aim = rmargin_aim - cwidth_aim; + adjust_print_pos(); +} + +static inline void goto_lmargin (void) +{ + hpos_aim = lmargin_aim; + adjust_print_pos(); +} + +static inline void goto_col0 (void) +{ + out_margin = 1; + hpos_aim = 0; + adjust_print_pos(); +} + + +uint8_t goto_prev_vtab (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + + do + { + --vpos_aim; + + if ((vpos_aim < tmargin) && (!out_margin)) // don't apply -1 offset + { + stop = 1; + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + else if (vpos_aim < 0) // don't apply -1 offset + { + stop = -1; + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + } while (!is_vtab(vpos_aim)); + + adjust_print_pos(); + return stop; +} + +uint8_t goto_next_vtab (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + + do + { + ++vpos_aim; + + if (((vpos_aim + lheight) > bmargin ) && (!out_margin)) // don't apply +1 offset + { + stop = 1; + break; + } + else if ((vpos_aim + lheight) > pheight) // don't apply +1 offset + { + stop = 1; + break; + } + } while (!is_vtab(vpos_aim)); + + adjust_print_pos(); + return stop; +} + +void move_back_vtab ( + const uint8_t n, + const uint8_t ignore_margin +) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i= VPOS_LIMIT)) + return 0; + + p = (uint8_t)(y >> 3); + q = ((uint8_t)y) & 7; + + return VTAB[p] & (1<= VPOS_LIMIT)) + return; + + p = (uint8_t)(y >> 3); + q = ((uint8_t)y) & 7; + + VTAB[p] |= (1<= VPOS_LIMIT)) + return; + + p = (uint8_t)(y >> 3); + q = ((uint8_t)y) & 7; + + VTAB[p] &= ~(1< rmargin_aim) && (!out_margin)) + { + stop = 1; + break; + } + else if ((hpos_aim + cwidth_aim) > lwidth) + { + stop = 1; + break; + } + } while (!is_htab(hpos_aim)); + + adjust_print_pos(); + return stop; +} + +void move_back_htab ( + const uint8_t n, + const uint8_t ignore_margin +) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i0) + dir = 1; + else if (x<0) + dir = -1; + else + { + adjust_print_pos(); + return; + } + + do + { + hpos_aim += dir; + if (is_htab(hpos_aim)) + i += dir; + + if (((hpos_aim + cwidth_aim) > rmargin_aim) && (!out_margin)) + { + hpos_aim = rmargin_aim - cwidth_aim; + break; + } + else if ((hpos_aim + cwidth_aim) > lwidth) + { + hpos_aim = lwidth - cwidth_aim; + break; + } + else if ((hpos_aim < lmargin_aim) && (!out_margin)) + { + hpos_aim = lmargin; + break; + } + else if (hpos_aim < 0) + { + hpos_aim = 0; + break; + } + + } while (i != x); + + adjust_print_pos(); +} + +uint8_t is_htab (const int16_t x) +{ + uint8_t p, q; + + if ((x < 0) || (x >= HPOS_LIMIT)) + return 0; + + p = (uint8_t)(x >> 3); + q = ((uint8_t)x) & 7; + + return HTAB[p] & (1<= HPOS_LIMIT)) + return; + + p = (uint8_t)(x >> 3); + q = ((uint8_t)x) & 7; + + HTAB[p] |= (1<= HPOS_LIMIT)) + return; + + p = (uint8_t)(x >> 3); + q = ((uint8_t)x) & 7; + + HTAB[p] &= ~(1<= lmargin_aim) && + ((hpos_aim + cwidth_aim) <= rmargin_aim) && + (vpos_aim >= tmargin - 1) && + ((vpos_aim + lheight) <= (bmargin + 1)) + ) + out_margin = 0; + + // outside current margins; adjust margins + if ((hpos > rmargin)/* && (hpos <= rmargin_aim)*/) + { + add_print_key(CODE_RMARGIN); + rmargin = hpos; + } + if ((hpos < lmargin) && (hpos >= lmargin_aim)) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + else if ((hpos == lmargin_aim) && (lmargin != lmargin_aim)) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + + // requested move outside right margin + if ((hpos_aim + cwidth_aim) > rmargin_aim) + { + // not allowed to leave; goto next line + if (!out_margin) + { + hpos_aim = lmargin_aim; + vpos_aim += lheight; + } + // requested move outside right edge; stay at edge + else if ((hpos_aim + cwidth_aim) > lwidth) + { + hpos_aim = lwidth - cwidth_aim; + } + } + + // requested move outside left margin + if (hpos_aim < lmargin_aim) + { + // not allowed to leave; stay at margin + if (!out_margin) + hpos_aim = lmargin_aim; + // requested move outside left edge; stay at edge + else if (hpos_aim < 0) + hpos_aim = 0; + } + + // requested move outside bottom margin; wait for new page + if ((vpos_aim + lheight) > (bmargin + 1)) + { + if (!out_margin ) // not allowed to leave + { + if (vpos_aim < pheight + tmargin) + vpos_aim = pheight + tmargin; // skip to next page top margin + set_alarm = 1; + set_led = 10; + wait_page = 1; + } + else if ((vpos_aim + lheight) > (pheight + 1)) // requested move outside bottom edge + { + set_alarm = 1; + set_led = 10; + wait_page = 1; + } + } + + // requested move outside top margin + if (vpos_aim < (tmargin - 1)) + { + // not allowed to leave; stay at top margin + if (!out_margin) + { + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + // requested move outside top edge; stay at edge + else if (vpos_aim < -1) + { + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + } + + // left from goal; move right + while (hpos < hpos_aim) + { + // move outside margin + if ((hpos + cwidth > rmargin) && (!margin_requested)) + { + add_print_key(KEY_MARGIN); + margin_requested = 1; + } + + // move right by 1 space + add_print_key(KEY_SPACE); + hpos += cwidth; + } + margin_requested = 0; + // outside margin; adjust margin + if (hpos > rmargin) + { + add_print_key(CODE_RMARGIN); + rmargin = hpos; + } + + // right from goal & from left margin; move to left margin + if ((hpos_aim <= lmargin) && (hpos > lmargin)) + { + add_print_key(CODE_RETURN); + hpos = lmargin; + } + + // right from goal; move left + while (hpos > hpos_aim) + { + // away by at least 1 space + if (hpos >= hpos_aim + cwidth) + { + // move outside margin + if ((hpos < lmargin + cwidth) && (!margin_requested)) + { + add_print_key(KEY_MARGIN); + margin_requested = 1; + } + + // move left by 1 space + add_print_key(KEY_BACK); + hpos -= cwidth; + } + // away by less than 1 space + else + { + // move outside margin + if ((hpos < lmargin + 1) && (!margin_requested)) + { + add_print_key(KEY_MARGIN); + margin_requested = 1; + } + + // move left by 1 unit + add_print_key(CODE_STEPLEFT); + --hpos; + } + } + margin_requested = 0; + // outside margin; adjust margin + if((hpos < lmargin) && (hpos >= lmargin_aim)) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + + // above goal; move down + while (vpos < vpos_aim) + { + add_print_key(CODE_HALFDOWN); + ++vpos; + } + + // below goal; move up + while (vpos > vpos_aim) + { + add_print_key(CODE_HALFUP); + --vpos; + } + + // next char will be out of margin + if (hpos + cwidth > rmargin) + { + add_print_key(KEY_MARGIN); + // margin_requested = 1; + } + + // out of page; renormalise coordinates + while (vpos_aim < -1) + { + vpos_aim += pheight; + vpos += pheight; + --ppos; + } + while ((vpos_aim + lheight) > (pheight + 1)) + { + vpos_aim -= pheight; + vpos -= pheight; + ++ppos; + } + + // opportunity to adjust char width + if (cwidth_todo & (hpos == lmargin)) + set_cwidth(cwidth_aim); +} + + +/* size, margin, spacing */ + +void set_pheight (const uint16_t y) +{ + pheight = y; + + // ensure at least 1 line in page & don't exceed limits + if (pheight < lheight) + pheight = lheight; + if (pheight > VPOS_LIMIT) + pheight = VPOS_LIMIT; + if (bmargin > pheight) + bmargin = pheight; + if(tmargin > bmargin - lheight) + tmargin = bmargin - lheight; +} + +void set_lheight (const uint8_t y) +{ + lheight = y; + + // ensure at least 1 line in page + if (pheight < lheight) + pheight = lheight; + if (tmargin + lheight > pheight) + tmargin = pheight - lheight; + if (tmargin + lheight > bmargin) + bmargin = tmargin + lheight; +} + +void set_tmargin (int16_t y) +{ + if (y<0) + y = 0; + + tmargin = y; + + if ((tmargin + lheight) > VPOS_LIMIT) + tmargin = VPOS_LIMIT - lheight; + if ((tmargin + lheight) > pheight) + pheight = tmargin + lheight; + if ((tmargin + lheight) > bmargin) + bmargin = tmargin + lheight; +} + +void set_bmargin (int16_t y) +{ + if (y<0) + y = 0; + + bmargin = y; + + if (bmargin < lheight) + bmargin = lheight; + if (bmargin > VPOS_LIMIT) + bmargin = VPOS_LIMIT; + if (bmargin > pheight) + pheight = bmargin; + if ((tmargin + lheight) > bmargin) + { + tmargin = bmargin - lheight; + } +} + +void set_bmargin_rel (const int16_t y) +{ + if (y>0) + set_bmargin(tmargin + y); // relative to top margin + else + set_bmargin(pheight + y); // relative to bottom edge +} + +static inline void set_tmargin_ch (uint8_t y) +{ + if(y==0xFF) + y = 0; + set_tmargin(lheight * (int16_t)y); +} + +static inline void set_bmargin_ch (uint8_t y) +{ + if(y==0xFF) + y = 0; + set_bmargin(lheight * (int16_t)y); +} + + +void set_lwidth (const uint16_t x) +{ + lwidth = + x; + + // ensure at least 1 character in line & don't exceed limits + if (lwidth < cwidth_aim) + lwidth = cwidth_aim; + if (lwidth > HPOS_LIMIT) + lwidth = HPOS_LIMIT; + if(rmargin_aim > lwidth) + rmargin_aim = lwidth; + if(lmargin_aim > (rmargin_aim - cwidth_aim)) + lmargin_aim = rmargin_aim - cwidth_aim; +} + +void set_cwidth (const uint8_t x) +{ + cwidth_aim = x; + + // ensure at least 1 character in line + if (lwidth < cwidth_aim) + lwidth = cwidth_aim; + if (lmargin + cwidth_aim > lwidth) + lmargin = lwidth - cwidth_aim; + if (lmargin + cwidth_aim > rmargin_aim) + rmargin_aim = lmargin_aim + cwidth_aim; + + if(hpos == lmargin) // opportunity to adjust at machine + { + if (x == WIDTH_10) + { + if (cwidth != WIDTH_10) + add_print_key(CODE_PITCH10); + cwidth = WIDTH_10; + } + else + { + if (cwidth != WIDTH_12) + add_print_key(CODE_PITCH12); + cwidth = WIDTH_12; + } + cwidth_todo = 0; + } + else + cwidth_todo = 1; +} + +void set_lmargin (int16_t x) +{ + if (x<0) + x = 0; + + lmargin_aim = x; + + if ((lmargin_aim + cwidth_aim) > HPOS_LIMIT) + lmargin_aim = HPOS_LIMIT - cwidth_aim; + if ((lmargin_aim + cwidth_aim) > lwidth) + lwidth = lmargin_aim + cwidth_aim; + if ((lmargin_aim + cwidth_aim) > rmargin_aim) + rmargin_aim = lmargin_aim + cwidth_aim; +} + +void set_rmargin (int16_t x) +{ + if (x<0) + x = 0; + + rmargin_aim = x; + + if (rmargin_aim < cwidth_aim) + rmargin_aim = cwidth_aim; + if (rmargin_aim > HPOS_LIMIT) + rmargin_aim = HPOS_LIMIT; + if (rmargin_aim > lwidth) + lwidth = rmargin_aim; + if((lmargin_aim + cwidth_aim) > rmargin_aim) + lmargin_aim = rmargin_aim - cwidth_aim; +} + +void set_rmargin_rel (const int16_t x) +{ + if (x>0) + set_rmargin(lmargin_aim + x); // relative to left margin + else + set_rmargin(lwidth + x); // relative to rigth edge +} + +static inline void set_lmargin_ch (uint8_t x) +{ + if(x==0xFF) + x = 0; + set_lmargin(cwidth_aim * (int16_t)x); +} + +static inline void set_rmargin_ch (uint8_t x) +{ + if(x==0xFF) + x = 0; + set_rmargin(cwidth_aim * (int16_t)x); +} + + +void set_theight (const uint8_t y) +{ + int16_t i; + + clear_vtab_all(); + + if (y==0) + return; + + set_vtab(0); + for (i=tmargin; i>0; i-=y) + set_vtab(i); + for (i=tmargin; i0; i-=x) + set_htab(i); + for (i=lmargin_aim; i>1)-1; + } + } +} + +static inline void set_serial_mode (const uint8_t setting) +{ + serial_mode = setting; + UCSR0C = setting; // the flags in SW and in register are the same :) +} + +static inline void set_encoding (const uint8_t setting) +{ + if (setting & ENC_UNI) + encoding = setting; + else if (setting < N_ENC) + { + CH_CP = CH_LIST[setting]; + KEYMAP_CP = KEYMAP_LIST[setting]; + C1 = ENC_C1[setting]; + encoding = setting; + if (C1) + GR_table[GR_index] = setting; + } +} + +static inline void set_encoding_GR (const uint8_t setting) +{ + if ((setting>=1) && (setting<=3)) + { + GR_index = setting; + set_encoding(GR_table[GR_index]); + } +} + +void set_flowcontrol (uint8_t setting) +{ + flow = setting & (FLOW_HW | FLOW_SW); + local_xonoff = 0; + remote_xonoff = XON; + unrequest_outcome(); + if (DIFF_BP(income_w, income_r, N_INCOME_BUFFER) < INCOME_BUFFER_HIGH) + accept_income(); + else + reject_income(); +} + + +void set_style (const uint8_t new_style) +{ + if ( // set bold + (new_style & STYLE_BOLD) && + (!(style & STYLE_BOLD)) + ) + add_print_key(CODE_BOLD); + else if ( // clear bold + (!(new_style & STYLE_BOLD)) && + (style & STYLE_BOLD) + ) + add_print_key(CODE_BOLD); + + if ( // set strong + (new_style & STYLE_STRONG) && + (!(style & STYLE_STRONG)) + ) + add_print_key(CODE_STRONG); + else if ( // clear strong + (!(new_style & STYLE_STRONG)) && + (style & STYLE_STRONG) + ) + add_print_key(CODE_WEAK); + + style = new_style; +} + +static inline void set_style_normal (void) +{ + set_style((style & STYLE_STRONG) | STYLE_NORMAL); +} + +static inline void set_style_bold (void) +{ + set_style(style | STYLE_BOLD); +} + +static inline void set_style_nobold (void) +{ + set_style(style & ~STYLE_BOLD); +} + +static inline void toggle_bold (void) +{ + set_style(style ^ STYLE_BOLD); +} + +static inline void set_style_under (void) +{ + set_style((style & ~STYLE_UNDER2) | STYLE_UNDER); +} + +static inline void set_style_under2 (void) +{ + set_style((style & ~STYLE_UNDER) | STYLE_UNDER2); +} + +static inline void set_style_nounder (void) +{ + set_style(style & ~(STYLE_UNDER | STYLE_UNDER2)); +} + +static void inline toggle_under (void) +{ + if (style & (STYLE_UNDER | STYLE_UNDER2)) + set_style_nounder(); + else + set_style_under(); +} + +static void inline toggle_under2 (void) +{ + if (style & (STYLE_UNDER | STYLE_UNDER2)) + set_style_nounder(); + else + set_style_under2(); +} + +static inline void set_style_cross (void) +{ + set_style(style | STYLE_CROSS); +} + +static inline void set_style_nocross (void) +{ + set_style(style & ~STYLE_CROSS); +} + +static inline void toggle_cross (void) +{ + set_style(style ^ STYLE_CROSS); +} + +static inline void set_style_over (void) +{ + set_style(style | STYLE_OVER); +} + +static inline void set_style_noover (void) +{ + set_style(style & ~STYLE_OVER); +} + +static inline void toggle_over (void) +{ + set_style(style ^ STYLE_OVER); +} + +static inline void set_style_strong (void) +{ + set_style(style | STYLE_STRONG); +} + +static inline void set_style_weak (void) +{ + set_style(style & ~STYLE_STRONG); +} + + +/* flow control */ + +void update_flowcontrol_hw (void) +{ + uint8_t out = 0; + + switch (flow & FLOW_HW) + { + case FLOW_HD_DCE: // we are the DCE; RTS/CTS + if (!income_requested()) // only assert CTS if there was RTS + break; + case FLOW_FD: // RTR/CTS + out = income_accepted; // assert RTR/CTS if we can accept incoming data + break; + case FLOW_HD_DTE: // we are the DTE; RTS/CTS + out = outcome_requested; // assert RTS if we want to send outcoming data + break; + default: // no flow control + out = 1; // always assert + } + if (out) + PORT_COMM &= ~SYNC_OUT; // assert RTR/RTS/CTS + else + PORT_COMM |= SYNC_OUT; // deassert RTR/RTS/CTS +} + +void update_flowcontrol_sw (void) +{ + if ((flow & FLOW_SW) == FLOW_XONOFF) + { + if (income_accepted) + { + if (local_xonoff != XON) + { + local_xonoff = XON; + send_xonoff = XON; + cancel_sleep(WAKEUP_OUTCOME); + } + } + else + { + if (local_xonoff != XOFF) + { + local_xonoff = XOFF; + send_xonoff = XOFF; + cancel_sleep(WAKEUP_OUTCOME); + } + } + } +} + +static inline void request_outcome (void) +{ + // we want to send outcoming data + outcome_requested = 1; + // this will only have an effect if we are the DTE in RTS/CTS mode + update_flowcontrol_hw(); +} + +static inline void unrequest_outcome (void) +{ + // we don't want to send outcoming data + outcome_requested = 0; + // this will only have an effect if we are the DTE in RTS/CTS mode + update_flowcontrol_hw(); +} + +static inline void accept_income (void) +{ + // we want to accept incoming data + income_accepted = 1; + // this will have effect in RTR/CTS mode or if we are the DCE in RTS/CTS mode + update_flowcontrol_hw(); + // this will have effect in XON/XOFF mode + update_flowcontrol_sw(); +} + +static inline void reject_income (void) +{ + // we don't want to accept incoming data + income_accepted = 0; + // this will have effect in RTR/CTS mode or if we are the DCE in RTS/CTS mode + update_flowcontrol_hw(); + // this will have effect in XON/XOFF mode + update_flowcontrol_sw(); +} + +uint8_t income_requested (void) +{ + // does remote machine want to send incoming data? + if ((flow & FLOW_HW) == FLOW_HD_DCE) // we are the DCE in RTS/CTS mode + { + if (PORT_COMM & SYNC_IN); // only if DTE asserted RTS + return 0; + } + return 0xFF; // all other cases, arrumed always true +} + +uint8_t outcome_accepted (void) +{ + // does remote machine accept outcoming data? + + // at first we assume YES, then we look for reasons for NO. + uint8_t accepted = 0xFF; + + switch (flow & FLOW_HW) + { + case FLOW_FD: // RTR/CTS + case FLOW_HD_DTE: // we are the DTE; RTS/CTS + if (PORT_COMM & SYNC_IN) // sorry, remote didn't assert RTR/CTS + accepted = 0; + break; + case FLOW_HD_DCE: // we are the DCE; RTS/CTS + if (!(PORT_COMM & SYNC_IN)) // sorry, remote wants to send now, not to receive + accepted = 0; + } + if ((flow & FLOW_SW) == FLOW_XONOFF) // XON/XOFF + { + if (remote_xonoff != XON) // sorry, remote said XOFF + accepted = 0; + } + return accepted; +} + + +/* eeprom settings storage */ + +static inline uint8_t eeprom_read (const uint16_t address) +{ + uint8_t data; + + while (EECR & (1<> 8; + checksum -= block[3]; + + block[1] = checksum; + + for(i=0; i<4; ++i) + { + eeprom_write(address + i, block[i]); + } +} + +void eeprom_erase_record (const uint16_t address) +{ + uint8_t i; + uint8_t io; + + EECR |= (1<= EEPROM_SIZE - 4) + store_all_config(); + else + { + switch(id) + { + case ID_BAUD: + eeprom_write_record(ee_address, ID_BAUD, baud); + break; + case ID_BITS: + eeprom_write_record(ee_address, ID_BITS, serial_mode); + break; + case ID_MODE: + eeprom_write_record(ee_address, ID_MODE, mode); + break; + case ID_NL_MODE: + eeprom_write_record(ee_address, ID_NL_MODE, nl_mode); + break; + case ID_BS_MODE: + eeprom_write_record(ee_address, ID_BS_MODE, bs_mode); + break; + case ID_ENCODING: + eeprom_write_record(ee_address, ID_ENCODING, encoding); + break; + case ID_REPLACE: + eeprom_write_record(ee_address, ID_REPLACE, replace); + break; + case ID_LWIDTH: + eeprom_write_record(ee_address, ID_LWIDTH, lwidth); + break; + case ID_LMARGIN: + eeprom_write_record(ee_address, ID_LMARGIN, lmargin_aim); + break; + case ID_RMARGIN: + eeprom_write_record(ee_address, ID_RMARGIN, rmargin_aim); + break; + case ID_PHEIGHT: + eeprom_write_record(ee_address, ID_PHEIGHT, pheight); + break; + case ID_TMARGIN: + eeprom_write_record(ee_address, ID_TMARGIN, tmargin); + break; + case ID_BMARGIN: + eeprom_write_record(ee_address, ID_BMARGIN, bmargin); + break; + case ID_HTAB: + eeprom_write_record(ee_address, ID_HTAB, twidth_ch); + break; + case ID_VTAB: + eeprom_write_record(ee_address, ID_VTAB, theight_ch); + break; + case ID_CWIDTH: + eeprom_write_record(ee_address, ID_CWIDTH, cwidth_aim); + break; + case ID_LHEIGHT: + eeprom_write_record(ee_address, ID_LHEIGHT, lheight); + break; + case ID_FLOW: + eeprom_write_record(ee_address, ID_FLOW, flow); + break; + case ID_PAPER: + eeprom_write_record(ee_address, ID_PAPER, paper); + break; + case ID_STYLE: + eeprom_write_record(ee_address, ID_STYLE, style); + break; + default: + return; + } + ee_address += 4; + eeprom_erase_record(ee_address); + } +} + +void load_config (void) +{ + uint8_t id; + uint16_t value; + + uint8_t ld_baud = baud; + uint8_t ld_serial_mode = serial_mode; + uint8_t ld_flow = flow; + uint8_t ld_encoding = encoding; + uint16_t ld_lwidth = lwidth; + uint16_t ld_lmargin = lmargin_aim; + uint16_t ld_rmargin = lmargin_aim; + uint16_t ld_pheight = pheight; + uint16_t ld_tmargin = tmargin; + uint16_t ld_bmargin = bmargin; + uint8_t ld_twidth = twidth_ch; + uint8_t ld_theight = theight_ch; + uint8_t ld_cwidth = cwidth_aim; + uint8_t ld_lheight = lheight; + + ee_address = 0; + while(1) + { + if (eeprom_read_record(ee_address, &id, &value)) + { + eeprom_erase_record(ee_address); + break; + } + switch (id) + { + case ID_BAUD: + ld_baud = (uint8_t)value; + break; + case ID_BITS: + ld_serial_mode = (uint8_t)value; + break; + case ID_MODE: + loaded_mode = (uint8_t)value; + break; + case ID_NL_MODE: + nl_mode = (uint8_t)value; + break; + case ID_BS_MODE: + bs_mode = (uint8_t)value; + break; + case ID_ENCODING: + ld_encoding = (uint8_t)value; + break; + case ID_REPLACE: + replace = (uint8_t)value; + break; + case ID_LWIDTH: + ld_lwidth = value; + break; + case ID_LMARGIN: + ld_lmargin = value; + break; + case ID_RMARGIN: + ld_rmargin = value; + break; + case ID_PHEIGHT: + ld_pheight = value; + break; + case ID_TMARGIN: + ld_tmargin =value; + break; + case ID_BMARGIN: + ld_bmargin =value; + break; + case ID_HTAB: + ld_twidth = value; + break; + case ID_VTAB: + ld_theight = (uint8_t)value; + break; + case ID_CWIDTH: + ld_cwidth = (uint8_t)value; + break; + case ID_LHEIGHT: + ld_lheight = value; + break; + case ID_FLOW: + ld_flow = (uint8_t)value; + break; + case ID_PAPER: + paper = (uint8_t)value; + break; + case ID_STYLE: + loaded_style = (uint8_t)value; + break; + default: + break; + } + ee_address +=4; + if (ee_address >= EEPROM_SIZE) + break; + } + + set_baudrate(ld_baud); + set_serial_mode(ld_serial_mode); + set_flowcontrol(ld_flow); + set_encoding(ld_encoding); + + set_pheight(ld_pheight); + set_lwidth(ld_lwidth); + set_lheight(ld_lheight); + set_cwidth(ld_cwidth); + set_tmargin(ld_tmargin); + set_bmargin(ld_bmargin); + set_lmargin(ld_lmargin); + set_rmargin(ld_rmargin); + set_theight_ch(ld_theight); + set_twidth_ch(ld_twidth); +} + + +/* sleep mode */ + +static inline void cancel_sleep (const uint8_t flag) +{ + SMCR &= ~(1 << SE); //disable sleep + keep_active |= flag; +} + +static inline void allow_sleep (const uint8_t flag) +{ + keep_active &= ~flag; +} + +static inline void goto_sleep (void) +{ + if (!keep_active) + { + SMCR = + (1 << SE) | // enable sleep + (0 << SM0); // idle + sleep_cpu(); + } +} + + +/* support util. */ + +uint8_t make_dec_string ( // create decimal text representation of number + uint8_t * const string, + uint32_t value, + const uint8_t min_digits, + const uint8_t max_digits +) +{ + int8_t i, j; + uint8_t text[10]; + uint8_t digit; + uint8_t first_digit = 9; + + for(i=9; i>=0; --i) + { + digit = value % 10; + value /= 10; + + if (digit != 0) + first_digit = i; + + text[i] = digit + 0x30; + } + if ((10 - min_digits) < first_digit) + first_digit = 10 - min_digits; + if ((10 - first_digit) > max_digits) + first_digit = 10 - max_digits; + + for (i=first_digit, j=0; i<10; ++i, ++j) + string[j] = text[i]; + + return 10 - first_digit; // return actual number of digits +} + +uint8_t make_hex_string ( // create hexadecimal text representation of number + uint8_t * const string, + uint32_t value, + const uint8_t min_digits, + const uint8_t max_digits, + const uint8_t uppercase +) +{ + int8_t i, j; + uint8_t text[8]; + uint8_t digit; + uint8_t first_digit = 7; + + for(i=7; i>=0; --i) + { + digit = value & 0x0f; + value >>=4; + + if (digit != 0) + first_digit = i; + + if (digit < 10) + text[i] = digit + 0x30; + else if (uppercase) + text[i] = digit + 0x41 - 10; + else + text[i] = digit + 0x61 - 10; + } + if ((8 - min_digits) < first_digit) + first_digit = 8 - min_digits; + if ((8 - first_digit) > max_digits) + first_digit = 8 - max_digits; + + for (i=first_digit, j=0; i<8; ++i, ++j) + string[j] = text[i]; + + return 8 - first_digit; // return actual number of digits +} + +uint32_t unit (uint32_t x, const uint16_t mul, const uint16_t div) +{ + if (div) // normal operation + { + if (mul != 1) + x *= mul; + if (div>1) + x /= div; + } + else if (mul) + x *= lheight; + else + x *= cwidth_aim; + return x; +} diff --git a/maszyna_.c b/maszyna_.c new file mode 100644 index 0000000..e749c98 --- /dev/null +++ b/maszyna_.c @@ -0,0 +1,5228 @@ +/* +Copyright 2022 Balthasar Szczepański + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. 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. + +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 HOLDER 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 +#include +#include +#include +#include + +#include "keyboard.h" +#include "keyboard-patterns.h" + + +// #define UART_DIV_75 13333 // 13333 1/3 75.0019 +0.010% + + #define UART_DIV_150 6667 // 6666 2/3 149.9925 -0.005% + + #define UART_DIV_300 3333 // 3333 1/3 300.0300 +0.010% + + #define UART_DIV_600 1667 // 1666 2/3 599.8800 -0.020% + + #define UART_DIV_1200 833 // 833 1/3 1200.4802 +0.040% + + #define UART_DIV_2400 417 // 416 2/3 2398.0815 -0.080% + + #define UART_DIV_4800 208 // 208 1/3 4807.6923 +0.160% + + #define UART_DIV_9600 104 // 104 1/6 9615.3846 +0.160% + + #define UART_DIV_19200 52 // 52 1/12 19230.7692 +0.160% + + #define UART_DIV_38400 26 // 26 1/24 38461.5384 +0.160% + +// #define UART_DIV_57600 17 // 17 17/36 58823.5294 +2.124% - + #define UART_DIV_115200 9 // 8 49/72 111111.1111 -3.549% - +// #define UART_DIV_230400 4 // 4 49/144 250000.0000 +8.507% - +// #define UART_DIV_460800 2 // 2 49/284 500000.0000 +8.507% - +// #define UART_DIV_500000 2 // 2 500000.0000 0.000% + +// #define UART_DIV_576000 2 // 1 53/72 500000.0000 -13.194% - +// #define UART_DIV_921600 1 // 1 49/576 1000000.0000 +8.507% + +// #define UART_DIV_1000000 1 // 1 1000000.0000 0.000% - + +#define UART_BAUD_150 0 +#define UART_BAUD_300 1 +#define UART_BAUD_600 2 +#define UART_BAUD_1200 3 +#define UART_BAUD_2400 4 +#define UART_BAUD_4800 5 +#define UART_BAUD_9600 6 +#define UART_BAUD_19200 7 +#define UART_BAUD_38400 8 +#define UART_BAUD_115200 9 +#define N_UART_BAUD 10 + +#define UART_DATA (7<' +#define R_QUEST CH_003F // '?' +#define R_UNDER CH_005F // '_' +#define R_SPACE CH_0020 // ' ' +#define R_IGNORE CH_NULL // '' + + +#define ESC_NONE 0 +#define ESC_P_POS 1 +#define ESC_ECMA_48 2 + + +#define ID_BAUD 1 +#define ID_MODE 2 +#define ID_NL_MODE 3 +#define ID_BS_MODE 4 +#define ID_ENCODING 5 +#define ID_REPLACE 6 +#define ID_BITS 7 +#define ID_LWIDTH 8 +#define ID_LMARGIN 9 +#define ID_RMARGIN 10 +#define ID_PHEIGHT 11 +#define ID_TMARGIN 12 +#define ID_BMARGIN 13 +#define ID_CWIDTH 14 +#define ID_LHEIGHT 15 +#define ID_HTAB 16 +#define ID_VTAB 17 +#define ID_PAPER 18 +#define ID_STYLE 19 +#define ID_FLOW 20 + + +#define MENU_NONE 0355 // choose something not present on kezboard +#define MENU_ENTER (KEY_ERASEW | KEYB_CODE) +#define MENU_OUTPUT KEY_ERASEW +#define MENU_EXIT KEY_MARGIN +#define MENU_CONFIRM KEY_RETURN +#define MENU_BAUD KEY_1 +#define MENU_BITS KEY_2 +#define MENU_FLOW KEY_3 +#define MENU_ECHO KEY_4 +#define MENU_NEWLINE KEY_5 +#define MENU_DELETE KEY_6 +#define MENU_REPLACE KEY_7 +#define MENU_ENCODING KEY_8 +#define MENU_PWIDTH KEY_Q +#define MENU_LMARGIN KEY_W +#define MENU_RMARGIN KEY_E +#define MENU_TWIDTH KEY_R +#define MENU_PHEIGHT KEY_T +#define MENU_TMARGIN KEY_Z +#define MENU_BMARGIN KEY_U +#define MENU_THEIGHT KEY_I +#define MENU_HTAB KEY_O +#define MENU_VTAB KEY_P +#define MENU_CWIDTH KEY_A +#define MENU_LHEIGHT KEY_S +#define MENU_PAPER KEY_D + +#define QMENU_ECHO CODE_AUTORETURN +#define QMENU_PAPER (KEY_RETURN | KEYB_CODE) +#define QMENU_EXIT (KEY_MARGIN | KEYB_CODE | KEYB_SHIFT) + + +#define TEXT_MENU_LIST ((uint8_t *)"MENU\r\n" \ + "1:baud 2:bits 3:flowctrl 4:echo 5:CR/LF 6:BS/DEL 7:replace 8:encoding\r\n" \ + "Q:width W:left E:right R:Twidth T:height Z:top U:bottom I:Theight\r\n" \ + "O:Htab P: Vtab A:Cwidth S:Lheight D:paper DEL: help ESC: exit\r\n> ") +#define TEXT_MENU_EXIT ((uint8_t *)"EXIT\r\n") +#define TEXT_MENU_BAUD ((uint8_t *)"SET BAUD RATE\r\n" \ + "1:150 2:300 3:600 4:1200 5:2400 6:4800 7:9600 8:19200 9:38400 0:115200\r\n" \ + "> ") +#define TEXT_MENU_BITS ((uint8_t *)"SET SERIAL MODE\r\n" \ + "1:8n1 2:8e1 3:8o1 4:8n2 5:8e2 6:8o2\r\n" \ + "7:7n1 8:7e1 9:7o1 10:7n2 11:7e2 12:7o2\r\n" \ + "> ") +#define TEXT_MENU_FLOW ((uint8_t *)"SET FLOW CONTROPL\r\n" \ + "HW: 1:FD(RTR/CTS) 2:HD,DTE(RTS/CTS) 3:HD,DCE(CTS/RTS) 4:none\r\n" \ + "SW: 5:XON/XOFF 6:none\r\n> ") +#define TEXT_MENU_NEWLINE ((uint8_t *)"SET NEWLINE HANDLING\r\n" \ + "RECEIVE: 1:CR->CRLF 2:LF->CRLF 3:any->CRLF 4:no change\r\n" \ + "SEND: 5:CR 6:LF 7:CRLF\r\n> ") +#define TEXT_MENU_ECHO ((uint8_t *)"SET LOCAL ECHO\r\n" \ + "1:ON 2:OFF\r\n> ") +#define TEXT_MENU_DELETE ((uint8_t *)"SET BACKSPACE/DELETE KEY CODE\r\n" \ + "1:BS=08 2:BS=7F 3:DEL=7F 4:DEL=08\r\n> ") +#define TEXT_MENU_REPLACE ((uint8_t *)"SET UNKNOWN CHARACTER HANDLING\r\n" \ + "1: 2:? 3:_ 4:SPACE 5:ignore\r\n> ") +#define TEXT_MENU_ENCODING ((uint8_t *)"SET CHARACTER ENCODING\r\n" \ + "1,2,3,4,9,10,13,15,16:ISO8859 1250,852:codepage 8:UTF-8\r\n> ") +#define TEXT_MENU_PWIDTH ((uint8_t *)"SET PAGE WIDTH (in columns)\r\n> ") +#define TEXT_MENU_LMARGIN ((uint8_t *)"SET LEFT MARGIN (in columns)\r\n> ") +#define TEXT_MENU_RMARGIN ((uint8_t *)"SET RIGHT MARGIN (in columns)\r\n> ") +#define TEXT_MENU_TWIDTH ((uint8_t *)"SET TEXT WIDTH (in columns)\r\n> ") +#define TEXT_MENU_PHEIGHT ((uint8_t *)"SET PAGE HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_TMARGIN ((uint8_t *)"SET TOP MARGIN (in lines)\r\n> ") +#define TEXT_MENU_BMARGIN ((uint8_t *)"SET BOTTOM MARGIN (in lines)\r\n> ") +#define TEXT_MENU_THEIGHT ((uint8_t *)"SET TEXT HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_HTAB ((uint8_t *)"SET TAB WIDTH (in columns)\r\n> ") +#define TEXT_MENU_VTAB ((uint8_t *)"SET TAB HEIGHT (in lines)\r\n> ") +#define TEXT_MENU_CWIDTH ((uint8_t *)"SET CHARACTER WIDTH\r\n" \ + "1:15CPI 2:12CPI 3:10CPI 4:6CPI 5:4CPI 6:3CPI\r\n> ") +#define TEXT_MENU_LHEIGHT ((uint8_t *)"SET LINE HEIGHT\r\n" \ + "1:6LPI 2:4LPI 3:3LPI 4:2LPI\r\n> ") +#define TEXT_MENU_PAPER ((uint8_t *)"SET_PAPER_TYPE\r\n" \ + "1:continuous 2:single pages\r\n> ") +#define TEXT_MENU_CANCEL ((uint8_t *)" CANCEL\r\n> ") +#define TEXT_MENU_OK ((uint8_t *)" OK\r\n> ") +#define TEXT_MENU_FAIL ((uint8_t *)" FAIL\r\n> ") + + +#define PRINT_DELAY 1 // 2? + +#define SCAN_HOLD 3 +#define SCAN_DEBOUNCE 3 // 3 * 10ms = 30ms +#define SCAN_DELAY 70 // 70 * 10ms = 700ms +#define SCAN_REPEAT 10 // 10 * 10ms = 100ms + +#define N_INCOME_BUFFER 256 +#define N_OUTCOME_BUFFER 64 +#define N_PRINT_BUFFER 128 +#define N_SCAN_BUFFER 64 +#define N_ESC_BUFFER 64 + +#define INCOME_BUFFER_LOW 8 +#define INCOME_BUFFER_HIGH 208 + + +#define MODE_WAIT 0b00000000 +#define MODE_TYPE 0b00000001 +#define MODE_TERM 0b00000010 +#define MODE_ECHO 0b00000100 + +#define NL_IMPLICIT_CR 0b00000001 +#define NL_IMPLICIT_LF 0b00000010 +#define NL_SEND_CR 0b00000100 +#define NL_SEND_LF 0b00001000 +#define NL_SEND_CRLF (NL_SEND_CR | NL_SEND_LF) +#define NL_CATCH_ALL (NL_IMPLICIT_CR | NL_IMPLICIT_LF) + +#define BS_BS 0b00000001 +#define BS_DEL 0b00000010 + +#define WAKEUP_INCOME 0b00000001 +#define WAKEUP_OUTCOME 0b00000010 +#define WAKEUP_SCAN 0b00000100 + +#define WIDTH_15 4 +#define WIDTH_12 5 +#define WIDTH_10 6 +#define WIDTH_6 10 +#define WIDTH_4_5 13 +#define WIDTH_4 15 +#define WIDTH_3 20 +#define N_CWIDTH 7 + +#define WIDTH_NARROW WIDTH_15 +#define WIDTH_NORMAL WIDTH_12 +#define WIDTH_WIDE WIDTH_10 + +#define HEIGHT_6 2 // 2 +#define HEIGHT_4 3 // 3 +#define HEIGHT_3 4 // 4 +#define HEIGHT_12 1 // 1 +#define HEIGHT_8 2 // 1.5 +#define HEIGHT_6M 2 // 2 46/127 +#define HEIGHT_4M 4 // 3 69/127 +#define HEIGHT_3M 5 // 4 92/127 +#define HEIGHT_12M 1 // 1 23/127 +#define HEIGHT_2 6 // 6 +#define N_LHEIGHT 10 + +#define HEIGHT_NORMAL HEIGHT_6 + +#define HPOS_LIMIT ((108-2) * WIDTH_NORMAL) +#define VPOS_LIMIT (144 * HEIGHT_NORMAL) +#define DEFAULT_LWIDTH (92 * WIDTH_NORMAL) +#define DEFAULT_PHEIGHT (72 * HEIGHT_NORMAL) +#define DEFAULT_LMARGIN ((12-1) * WIDTH_NORMAL) +#define DEFAULT_LMARGIN_AIM (0 * WIDTH_NORMAL) +#define DEFAULT_RMARGIN ((90-1) * WIDTH_NORMAL) +#define DEFAULT_RMARGIN_AIM ((80 * WIDTH_NORMAL)+DEFAULT_LMARGIN_AIM) +#define DEFAULT_TMARGIN (0 * HEIGHT_NORMAL) +#define DEFAULT_BMARGIN ((56 * HEIGHT_NORMAL)+DEFAULT_TMARGIN) +#define DEFAULT_TWIDTH_CH 4 +#define DEFAULT_THEIGHT_CH 4 + +#define LMARGIN_PRESET (12 * WIDTH_NORMAL) +#define RMARGIN_PRESET (2 * WIDTH_NORMAL) + + +#define HTAB_SIZE (((HPOS_LIMIT-1)/8)+1) +#define VTAB_SIZE (((VPOS_LIMIT-1)/8)+1) + + +#define HUNIT_MUL_CH 0 +#define HUNIT_DIV_CH 0 +#define HUNIT_MUL_MM 300 +#define HUNIT_DIV_MM 127 +#define HUNIT_MUL_CDP 1 +#define HUNIT_DIV_CDP 12 +#define HUNIT_MUL_DD 4 +#define HUNIT_DIV_DD 45 +#define HUNIT_MUL_MIL 3 +#define HUNIT_DIV_MIL 50 +#define HUNIT_MUL_BMU 1 +#define HUNIT_DIV_BMU 20 +#define HUNIT_MUL_UM 3 +#define HUNIT_DIV_UM 1270 +#define HUNIT_MUL_DP 1 +#define HUNIT_DIV_DP 12 + +#define VUNIT_MUL_CH 1 +#define VUNIT_DIV_CH 0 +#define VUNIT_MUL_MM 60 +#define VUNIT_DIV_MM 127 +#define VUNIT_MUL_CDP 1 +#define VUNIT_DIV_CDP 60 +#define VUNIT_MUL_DD 4 +#define VUNIT_DIV_DD 225 +#define VUNIT_MUL_MIL 3 +#define VUNIT_DIV_MIL 250 +#define VUNIT_MUL_BMU 1 +#define VUNIT_DIV_BMU 100 +#define VUNIT_MUL_UM 3 +#define VUNIT_DIV_UM 6350 +#define VUNIT_MUL_DP 1 +#define VUNIT_DIV_DP 60 + + +#define PF_TCOMM_BASIC_TALL 0 +#define PF_TCOMM_BASIC_WIDE 1 +#define PF_A4_BASIC_TALL 2 +#define PF_A4_BASIC_WIDE 3 +#define PF_LETTER_TALL 4 +#define PF_LETTER_WIDE 5 +#define PF_A4_EXT_TALL 6 +#define PF_A4_EXT_WIDE 7 +#define PF_LEGAL_TALL 8 +#define PF_LEGAL_WIDE 9 +#define PF_A4_SHORT 10 +#define PF_A4_LONG 11 +#define PF_B5_SHORT 12 +#define PF_B5_LONG 13 +#define PF_B4_SHORT 14 +#define PF_B4_LONG 15 +#define N_PF 16 + +#define LWIDTH_TCOMM_BASIC_TALL 462 // 92.4 7.7" +#define LWIDTH_TCOMM_BASIC_WIDE 625 // 125 10 5/12" +#define LWIDTH_A4_BASIC_TALL 462 // 92.4 7.7" +#define LWIDTH_A4_BASIC_WIDE 660 // 132 11" +#define LWIDTH_LETTER_TALL 480 // 96 8" +#define LWIDTH_LETTER_WIDE 625 // 125 10 5/12" +#define LWIDTH_A4_EXT_TALL 462 // 92.4 7.7" +#define LWIDTH_A4_EXT_WIDE 660 // 132 11" +#define LWIDTH_LEGAL_TALL 480 // 96 8" +#define LWIDTH_LEGAL_WIDE 810 // 162 13.5" +#define LWIDTH_A4_SHORT 450 // 90 7.5" +#define LWIDTH_A4_LONG 655 // 131 10 11/12" +#define LWIDTH_B5_SHORT 375 // 75 6.25" +#define LWIDTH_B5_LONG 555 // 111 9.25" +#define LWIDTH_B4_SHORT 555 // 111 9.25" +#define LWIDTH_B4_LONG 785 // 157 13 1/12" + +#define PHEIGHT_TCOMM_BASIC_TALL 110 // 55 9 1/6" +#define PHEIGHT_TCOMM_BASIC_WIDE 76 // 38 6 1/3" +#define PHEIGHT_A4_BASIC_TALL 118 // 59 9 5/6" +#define PHEIGHT_A4_BASIC_WIDE 76 // 38 6 1/3" +#define PHEIGHT_LETTER_TALL 112 // 56 9 1/3" +#define PHEIGHT_LETTER_WIDE 80 // 40 6 2/3" +#define PHEIGHT_A4_EXT_TALL 132 // 63 11" +#define PHEIGHT_A4_EXT_WIDE 88 // 44 7 1/3" +#define PHEIGHT_LEGAL_TALL 148 // 74 12 1/3" +#define PHEIGHT_LEGAL_WIDE 80 // 40 6 2/3" +#define PHEIGHT_A4_SHORT 118 // 59 9 5/6" +#define PHEIGHT_A4_LONG 76 // 38 6 1/3" +#define PHEIGHT_B5_SHORT 98 // 49 8 1/6" +#define PHEIGHT_B5_LONG 64 // 32 5 1/13" +#define PHEIGHT_B4_SHORT 114 // 59 9.5" +#define PHEIGHT_B4_LONG 98 // 49 8 1/6" + + +#define STYLE_NORMAL 0b00000000 +#define STYLE_BOLD 0b00000001 +#define STYLE_UNDER 0b00000010 +#define STYLE_UNDER2 0b00000100 +#define STYLE_OVER 0b00001000 +#define STYLE_CROSS 0b00010000 +#define STYLE_STRONG 0b10000000 + + +#define PAPER_SINGLE 0 +#define PAPER_CONTINUOUS 1 + + +#define EEPROM_SIZE (4 * 1024) + + +#define CTRL_IND (buffer+1), &buffer_pos, &p_ind, &sp_ind + + +// port A, keyboard row +#define PORT_ROW PORTA +#define DDR_ROW DDRA +#define PIN_ROW PINA + +// port C, keyboard column +#define PORT_COL PORTC +#define DDR_COL DDRC +#define PIN_COL PINC + +// port B, key output select +#define PORT_KEY PORTB +#define DDR_KEY DDRB + +// port D, control of state, active low +#define PORT_CTRL PORTD +#define DDR_CTRL DDRD + +#define LED 0b00010000 // out +#define KEY 0b00100000 // out +#define EN_PRINT 0b01000000 // out +#define EN_KEYB 0b10000000 // out + +#define MASK_CTRL (LED|KEY|EN_PRINT|EN_KEYB) + +// port D, communication +#define PORT_COMM PORTD +#define DDR_COMM DDRD +#define PIN_COMM PIND + +#define RX 0b00000001 // in +#define TX 0b00000010 // out +#define SYNC_IN 0b00000100 // in +#define SYNC_OUT 0b00001000 // out + +#define MASK_COMM (RX|TX|SYNC_IN|SYNC_OUT) + +#define ADVANCE_BP(P, N) ((P<(N-1)) ? (++P) : (P=0)) +#define DIFF_BP(W, R, N) ((W> 8); + // UBRR0L = (uint8_t) ((UART_DIV[baud]-1) & 0xff); + UBRR0 = UART_DIV[baud]-1; + UCSR0A = (1<=0) && (setting<=3)) + { + GR_index = setting; + set_encoding(GR_table[GR_index]); + } +} + +static inline uint8_t eeprom_read (const uint16_t address) +{ + uint8_t data; + // add_income('R'); + // add_income(' '); + // add_income((address>>12)+'0'); + // add_income(((address>>8)&0xf)+'0'); + // add_income(((address>>4)&0xf)+'0'); + // add_income((address&0xf)+'0'); + // add_income(' '); + + while (EECR & (1<>4)+'0'); + // add_income((data&0xf)+'0'); + // add_income('\r'); + // add_income('\n'); + + return data; +} + +static inline void eeprom_write (const uint16_t address, const uint8_t data) +{ + // add_income('W'); + // add_income(' '); + // add_income((address>>12)+'0'); + // add_income(((address>>8)&0xf)+'0'); + // add_income(((address>>4)&0xf)+'0'); + // add_income((address&0xf)+'0'); + // add_income(' '); + // add_income((data>>4)+'0'); + // add_income((data&0xf)+'0'); + // add_income('\r'); + // add_income('\n'); + + while (EECR & (1<> 8; + checksum -= block[3]; + + block[1] = checksum; + + // add_outcome_str("STORE "); + // add_outcome_hex(address,4); + // add_outcome(' '); + // add_outcome_hex(block[0],2); + // add_outcome(' '); + // add_outcome_hex(block[1],2); + // add_outcome(' '); + // add_outcome_hex(block[2],2); + // add_outcome(' '); + // add_outcome_hex(block[3],2); + // add_outcome_str("\r\n"); + + for(i=0; i<4; ++i) + { + eeprom_write(address + i, block[i]); + } +} + +void eeprom_erase_record (const uint16_t address) +{ + uint8_t i; + uint8_t io; + + EECR |= (1<= EEPROM_SIZE - 4) + store_all_config(); + else + { + switch(id) + { + case ID_BAUD: + eeprom_write_record(ee_address, ID_BAUD, baud); + break; + case ID_BITS: + eeprom_write_record(ee_address, ID_BITS, serial_mode); + break; + case ID_MODE: + eeprom_write_record(ee_address, ID_MODE, mode); + break; + case ID_NL_MODE: + eeprom_write_record(ee_address, ID_NL_MODE, nl_mode); + break; + case ID_BS_MODE: + eeprom_write_record(ee_address, ID_BS_MODE, bs_mode); + break; + case ID_ENCODING: + eeprom_write_record(ee_address, ID_ENCODING, encoding); + break; + case ID_REPLACE: + eeprom_write_record(ee_address, ID_REPLACE, replace); + break; + case ID_LWIDTH: + eeprom_write_record(ee_address, ID_LWIDTH, lwidth); + break; + case ID_LMARGIN: + eeprom_write_record(ee_address, ID_LMARGIN, lmargin_aim); + break; + case ID_RMARGIN: + eeprom_write_record(ee_address, ID_RMARGIN, rmargin_aim); + break; + case ID_PHEIGHT: + eeprom_write_record(ee_address, ID_PHEIGHT, pheight); + break; + case ID_TMARGIN: + eeprom_write_record(ee_address, ID_TMARGIN, tmargin); + break; + case ID_BMARGIN: + eeprom_write_record(ee_address, ID_BMARGIN, bmargin); + break; + case ID_HTAB: + eeprom_write_record(ee_address, ID_HTAB, twidth_ch); + break; + case ID_VTAB: + eeprom_write_record(ee_address, ID_VTAB, theight_ch); + break; + case ID_CWIDTH: + eeprom_write_record(ee_address, ID_CWIDTH, cwidth_aim); + break; + case ID_LHEIGHT: + eeprom_write_record(ee_address, ID_LHEIGHT, lheight); + break; + case ID_FLOW: + eeprom_write_record(ee_address, ID_FLOW, flow); + break; + case ID_PAPER: + eeprom_write_record(ee_address, ID_PAPER, paper); + break; + case ID_STYLE: + eeprom_write_record(ee_address, ID_STYLE, style); + break; + default: + return; + } + ee_address += 4; + eeprom_erase_record(ee_address); + } +} + +void load_config (void) +{ + uint8_t block[4]; + uint8_t i; + uint8_t checksum; + uint8_t ld_baud = baud; + uint8_t ld_serial_mode = serial_mode; + uint8_t ld_flow = flow; + uint8_t ld_encoding = encoding; + uint16_t ld_lwidth = lwidth; + uint16_t ld_lmargin = lmargin_aim; + uint16_t ld_rmargin = lmargin_aim; + uint16_t ld_pheight = pheight; + uint16_t ld_tmargin = tmargin; + uint16_t ld_bmargin = bmargin; + uint8_t ld_twidth = twidth_ch; + uint8_t ld_theight = theight_ch; + uint8_t ld_cwidth = cwidth_aim; + uint8_t ld_lheight = lheight; + + ee_address = 0; + while(1) + { + // add_outcome_str("LOAD "); + // add_outcome_hex(ee_address,4); + // add_outcome(' '); + checksum = 0; + for (i=0; i<4; ++i) + { + block[i] = eeprom_read(ee_address + i); + checksum += block[i]; + } + // add_outcome_hex(block[0],2); + // add_outcome(' '); + // add_outcome_hex(block[1],2); + // add_outcome(' '); + // add_outcome_hex(block[2],2); + // add_outcome(' '); + // add_outcome_hex(block[3],2); + // add_outcome(' '); + if (checksum!=0) + { + eeprom_erase_record(ee_address); + break; + // add_outcome_str("BAD CHECKSUM\r\n"); + } + switch (block[0]) + { + case ID_BAUD: + ld_baud = block[2]; + // add_outcome_str("BAUD "); + // add_outcome_dec(ld_baud, 1); + break; + case ID_BITS: + ld_serial_mode = block[2]; + // add_outcome_str("BITS "); + // add_outcome_dec(ld_serial_mode, 1); + break; + case ID_MODE: + loaded_mode = block[2]; + // add_outcome_str("mode "); + // add_outcome_dec(loaded_mode, 1); + break; + case ID_NL_MODE: + nl_mode = block[2]; + // add_outcome_str("NL "); + // add_outcome_dec(nl_mode, 1); + break; + case ID_BS_MODE: + bs_mode = block[2]; + // add_outcome_str("BS "); + // add_outcome_dec(bs_mode, 1); + break; + case ID_ENCODING: + ld_encoding = block[2]; + // add_outcome_str("ENCODING "); + // add_outcome_dec(ld_encoding, 1); + break; + case ID_REPLACE: + replace = block[2]; + // add_outcome_str("REPLACE "); + // add_outcome_dec(replace, 1); + break; + case ID_LWIDTH: + ld_lwidth = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("LWIDTH "); + // add_outcome_dec(ld_lwidth, 1); + break; + case ID_LMARGIN: + ld_lmargin = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("LMARGIN "); + // add_outcome_dec(ld_lmargin, 1); + break; + case ID_RMARGIN: + ld_rmargin = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("RMARGIN "); + // add_outcome_dec(ld_rmargin, 1); + break; + case ID_PHEIGHT: + ld_pheight = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("PHEIGHT "); + // add_outcome_dec(ld_pheight, 1); + break; + case ID_TMARGIN: + ld_tmargin =(((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("TMARGIN "); + // add_outcome_dec(ld_tmargin, 1); + break; + case ID_BMARGIN: + ld_bmargin =(((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("BMARGIN "); + // add_outcome_dec(ld_bmargin, 1); + break; + case ID_HTAB: + ld_twidth = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("HTAB "); + // add_outcome_dec(ld_twidth, 1); + break; + case ID_VTAB: + ld_theight = block[2]; + // add_outcome_str("VTAB "); + // add_outcome_dec(ld_theight, 1); + break; + case ID_CWIDTH: + ld_cwidth = block[2]; + // add_outcome_str("CWIDTH "); + // add_outcome_dec(ld_cwidth, 1); + break; + case ID_LHEIGHT: + ld_lheight = (((uint16_t)block[3])<<8)|block[2]; + // add_outcome_str("LHEIGHT "); + // add_outcome_dec(ld_lheight, 1); + break; + case ID_FLOW: + ld_flow = block[2]; + // add_outcome_str("FLOW "); + // add_outcome_dec(ld_flow, 1); + break; + case ID_PAPER: + paper = block[2]; + // add_outcome_str("PAPER "); + // add_outcome_dec(paper, 1); + break; + case ID_STYLE: + loaded_style = block[2]; + // add_outcome_str("STYLE "); + // add_outcome_dec(loaded_style, 1); + break; + default: + break; + } + // add_outcome_str("\r\n"); + ee_address +=4; + if (ee_address >= EEPROM_SIZE) + break; + } + set_baudrate(ld_baud); + set_serial_mode(ld_serial_mode); + set_flowcontrol(ld_flow); + set_encoding(ld_encoding); + + set_pheight(ld_pheight); + set_lwidth(ld_lwidth); + set_lheight(ld_lheight); + set_cwidth(ld_cwidth); + set_tmargin(ld_tmargin); + set_bmargin(ld_bmargin); + set_lmargin(ld_lmargin); + set_rmargin(ld_rmargin); + set_theight_ch(ld_theight); + set_twidth_ch(ld_twidth); +} + +static inline void scan_keyboard (void) +{ + static uint8_t base_state [8] = {0,0,0,0,0,0,0,0}; + static uint8_t last_state [8] = {0,0,0,0,0,0,0,0}; + + static uint8_t shift_state = 0; + static uint8_t code_state = 0; + + static uint8_t last_row = 0b00000000; + static uint8_t last_col = 0b00000000; + static uint8_t hold_count = 0; + static uint8_t key_debounce[8] = {0,0,0,0,0,0,0,0}; + static uint8_t key_repeat[8] = {0,0,0,0,0,0,0,0}; + + uint8_t row, col; + uint8_t ind, ind_base, ind_off; + uint8_t filtered_state; + + uint8_t send_event = 0; + + col = PIN_COL; + row = PIN_ROW; + + if (row == last_row) + ++hold_count; + else + { + if (hold_count >= SCAN_HOLD) + { + switch(last_row) + { + case KEYB_0: + ind = 0; + ind_base = KEYB_ROW_0; + break; + case KEYB_1: + ind = 1; + ind_base = KEYB_ROW_1; + break; + case KEYB_2: + ind = 2; + ind_base = KEYB_ROW_2; + break; + case KEYB_3: + ind = 3; + ind_base = KEYB_ROW_3; + break; + case KEYB_4: + ind = 4; + ind_base = KEYB_ROW_4; + break; + case KEYB_5: + ind = 5; + ind_base = KEYB_ROW_5; + break; + case KEYB_6: + ind = 6; + ind_base = KEYB_ROW_6; + break; + case KEYB_7: + ind = 7; + ind_base = KEYB_ROW_7; + break; + default: + ind = 0xff; + } + if (ind < 8) + { + if (last_col != last_state[ind]) + key_debounce[ind] = 0; + else + { + if(key_debounce[ind] < SCAN_DEBOUNCE) + { + ++key_debounce[ind]; + if(key_debounce[ind] == SCAN_DEBOUNCE) + { + base_state[ind] = last_col; + key_repeat[ind] = SCAN_DEBOUNCE - 1; + send_event = 1; + } + } + } + + if (key_repeat[ind] >= SCAN_DELAY) + { + key_repeat[ind] -= SCAN_REPEAT; + send_event = 1; + } + ++key_repeat[ind]; + + if (send_event) + { + send_event=0; + filtered_state = base_state[ind]; + if (ind==KEYB_MOD_IND) + { + shift_state = (filtered_state & KEYB_SHIFT_BIT) ? KEYB_SHIFT : 0; + code_state = (filtered_state & KEYB_CODE_BIT) ? KEYB_CODE : 0; + filtered_state &= ~(KEYB_SHIFT_BIT | KEYB_CODE_BIT); + } + switch (filtered_state) + { + case KEYB_0: + ind_off = KEYB_COL_0; + break; + case KEYB_1: + ind_off = KEYB_COL_1; + break; + case KEYB_2: + ind_off = KEYB_COL_2; + break; + case KEYB_3: + ind_off = KEYB_COL_3; + break; + case KEYB_4: + ind_off = KEYB_COL_4; + break; + case KEYB_5: + ind_off = KEYB_COL_5; + break; + case KEYB_6: + ind_off = KEYB_COL_6; + break; + case KEYB_7: + ind_off = KEYB_COL_7; + break; + default: + ind_off = 0xff; + break; + } + if (ind_off <= KEYB_COL_7) + { + add_scan(ind_base | ind_off | shift_state | code_state); + } + } + last_state[ind] = last_col; + } + } + hold_count=0; + } + last_row = row; + last_col = col; +} + +void add_scan (const uint8_t key) +{ + if (FULL_BP(scan_w, scan_r, N_SCAN_BUFFER)) + { + set_led = 10; + set_alarm = 1; + return; + } + + scan_buffer[scan_w] = key; + ADVANCE_BP(scan_w, N_SCAN_BUFFER); + + cancel_sleep(WAKEUP_SCAN); +} + +void handle_scan (void) +{ + uint8_t key; + uint8_t ch; + uint16_t uni_ch; + uint8_t uni_bytes; + uint8_t uni_buffer[3]; + + static uint8_t ctrl = 0; + + + cli(); + if (EMPTY_BP(scan_w, scan_r, N_SCAN_BUFFER)) + { + allow_sleep(WAKEUP_SCAN); + sei(); + } + else + { + sei(); + + key = scan_buffer[scan_r]; + ADVANCE_BP(scan_r, N_SCAN_BUFFER); + + if (mode == MODE_WAIT) + { + if (key & (KEYB_SHIFT|KEYB_CODE)) + become_terminal(); + else + become_typewriter(); + } + + if (mode & MODE_TERM) + { + switch (key) + { + case KEY_CAPS: + if(!wait_page) + break; + case SKEY_CAPS: + vpos = tmargin; + vpos_aim = tmargin; + wait_page = 0; + set_alarm = 1; + break; + case CODE_BOLD: + toggle_bold(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case CODE_UNDER: + toggle_under(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case CODE_STRONG: + set_style_strong(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case CODE_WEAK: + set_style_weak(); + store_single_config(ID_STYLE); + set_alarm=1; + break; + case CODE_LINE1: + set_lheight(HEIGHT_6); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case CODE_LINE1_5: + set_lheight(HEIGHT_4); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case CODE_LINE2: + set_lheight(HEIGHT_3); + store_single_config(ID_LHEIGHT); + set_alarm=1; + break; + case CODE_PITCH10: + set_cwidth(WIDTH_10); + store_single_config(ID_CWIDTH); + set_alarm=1; + break; + case CODE_PITCH12: + set_cwidth(WIDTH_12); + store_single_config(ID_CWIDTH); + set_alarm=1; + break; + case QMENU_ECHO: + mode ^= MODE_ECHO; + store_single_config(ID_MODE); + set_alarm=1; + break; + case QMENU_PAPER: + if (paper == PAPER_SINGLE) + paper = PAPER_CONTINUOUS; + else + paper = PAPER_SINGLE; + store_single_config(ID_PAPER); + set_alarm=1; + break; + case QMENU_EXIT: + become_typewriter(); + break; + default: + if (handle_menu(key)) + ctrl = 0; + else + { + switch(key) + { + case KEY_BACK: + add_ch((bs_mode & BS_BS) ? 0x08 : 0x7f); + break; + case KEY_ERASE1: + add_ch((bs_mode & BS_DEL) ? 0x7f : 0x08); + break; + case KEY_ERASEW: + ctrl = 1; + break; + case KEY_RETURN: + case SKEY_RETURN: + if (nl_mode & NL_SEND_CR) + add_ch('\r'); + if (nl_mode & NL_SEND_LF) + add_ch('\n'); + break; + default: + if (encoding & ENC_UNI) + { + uni_ch = KEYMAP_UNI[key]; + if (uni_ch >= 0x0080) + { + uni_buffer[0] = 0b10000000; + if (uni_ch >= 0x0800) + { + uni_bytes = 3; + uni_buffer[1] = 0b10000000; + uni_buffer[2] = 0b11100000; + } + else + { + uni_bytes = 2; + uni_buffer[1] = 0b11000000; + } + uni_buffer[0] |= uni_ch & 0b00111111; + uni_ch >>= 6; + uni_buffer[1] |= uni_ch & 0b00111111; + uni_ch >>= 6; + uni_buffer[2] |= uni_ch; + while (uni_bytes) + { + --uni_bytes; + add_ch(uni_buffer[uni_bytes]); + } + } + else if (uni_ch) + { + if (ctrl) + { + uni_ch &= 0x1f; + ctrl = 0; + } + add_ch(uni_ch); + } + } + else + { + ch = KEYMAP_CP[key]; + if (ch) + { + if (ctrl) + { + ch &= 0x1f; + ctrl = 0; + } + add_ch(ch); + } + } + break; + } + } + } + } + } +} + +static inline void goto_sleep (void) +{ + if (!keep_active) + { + SMCR = + (1 << SE) | // enable sleep + (0 << SM0); // idle + sleep_cpu(); + } +} + +static inline void cancel_sleep (const uint8_t flag) +{ + SMCR &= ~(1 << SE); //disable sleep + keep_active |= flag; +} + +static inline void allow_sleep (const uint8_t flag) +{ + keep_active &= ~flag; +} + + +ISR(TIMER2_COMPA_vect) +{ + scan_keyboard(); + + static uint8_t print_timer = 0; + static uint16_t led_timer = 0; + static uint8_t led_on = 0; + + if (print_timer >= PRINT_DIV-1) + { + print_timer = 0; + handle_print(); + if ((flow & FLOW_HW) == FLOW_HD_DCE) + update_flowcontrol_hw(); + } + else + ++print_timer; + + if (led_timer >= LED_DIV-1) + { + led_timer = 0; + if (set_led) + { + PORT_CTRL &= ~LED; + if (set_led > led_on) + led_on = set_led; + set_led = 0; + } + else if(led_on) + { + --led_on; + if (!led_on) + PORT_CTRL |= LED; + } + } + ++led_timer; + + // goto_sleep(); +} + +void add_income (const uint8_t in, const uint8_t blocking) +{ + while (FULL_BP(income_w, income_r, N_INCOME_BUFFER)) + { + if (blocking) + handle_income(); + else + { + set_led = 10; + set_alarm = 1; + reject_income(); + return; + } + } + + set_led = 2; + + income_buffer[income_w] = in; + ADVANCE_BP(income_w, N_INCOME_BUFFER); + + if (DIFF_BP(income_w, income_r, N_INCOME_BUFFER) >= INCOME_BUFFER_HIGH) // buffer getting full + reject_income(); + + cancel_sleep(WAKEUP_INCOME); +} + +void handle_income (void) +{ + uint8_t in; + + static uint8_t uni_bytes = 0; + static uint32_t uni_ch = 0; + + if (wait_page) + { + if (paper == PAPER_CONTINUOUS) + wait_page = 0; + else + { + set_led = 2; + return; + } + } + + cli(); + if (EMPTY_BP(income_w, income_r, N_BUFER_INCOME)) + { + allow_sleep(WAKEUP_INCOME); + sei(); + accept_income(); + } + else + { + sei(); + + in = income_buffer[income_r]; + ADVANCE_BP(income_r, N_INCOME_BUFFER); + + if (DIFF_BP(income_w, income_r, N_INCOME_BUFFER) < INCOME_BUFFER_LOW) // buffer getting free + accept_income(); // resume communication please + + if (mode == MODE_WAIT) + become_terminal(); + + if (mode & MODE_TERM) + { + if (encoding && ENC_UNI) // UTF-8 + { + if (uni_bytes && (in < 0x80)) // interrupted utf-8 sequence + { + add_print_ch(CH_UNKN); + uni_bytes = 0; + } + + if ((in & 0b11000000) == 0b10000000) // continuation of sequence + { + if (uni_bytes) // byte was expected. handle it + { + uni_ch <<= 6; + uni_ch |= in & 0b00111111; + --uni_bytes; + if (!uni_bytes) // finished + { + if (uni_ch < CH_LIMIT) + + + + + + + + + + if (uni_bytes && (in < 0x80)) // interrupted utf-8 sequence + { + add_print_ch(CH_UNKN); + uni_bytes = 0; + } + + if (handle_ctrl(in)) + { + } + else if (in < 0x80) // ascii + { + add_print_ch(CH_ASCII[in]); + } + else if (encoding & ENC_UNI) // utf-8 + { + if ((in & 0b11000000) == 0b10000000) // continuation + { + if (uni_bytes) + { + uni_ch <<= 6; + uni_ch |= in & 0b00111111; + --uni_bytes; + if (!uni_bytes) // finished + { + if (uni_ch < CH_LIMIT) + add_print_ch(UNI_TABLE[uni_ch]); + else + add_print_ch(CH_UNKN); + } + } + else + add_print_ch(CH_UNKN); + } + else // new char + { + if (uni_bytes) + add_print_ch(CH_UNKN); + if ((in & 0b11100000) == 0b11000000) // 2 byte + { + uni_ch = in & 0b00011111; + uni_bytes = 1; + } + else if ((in & 0b11110000) == 0b11100000) // 3 byte + { + uni_ch = in & 0b00001111; + uni_bytes = 2; + } + else if ((in & 0b11111000) == 0b11110000) // 4 byte + { + uni_ch = in & 0b00000111; + uni_bytes = 3; + } + else if ((in & 0b11111100) == 0b11111000) // 5 byte [!] + { + uni_ch = in & 0b00000011; + uni_bytes = 4; + } + else if ((in & 0b11111110) == 0b11111100) // 6 byte [!] + { + uni_ch = in & 0b00000001; + uni_bytes = 5; + } + else if (in == 0b11111110) // 7 byte [!] + { + uni_ch = 0; + uni_bytes = 6; + } + else // ??? + { + uni_bytes = 0; + add_print_ch(CH_UNKN); + } + } + } + else // codepage + { + if (uni_bytes) // leftover + { + uni_bytes = 0; + add_print_ch(CH_UNKN); + } + add_print_ch(CH_CP[in]); + } + } + } +} + +void add_outcome (const uint8_t out) +{ + if ( + (out & 0x80) && // high bit set + ((serial_mode & UART_DATA) == UART_DATA_7) // serial set to 7 bits + ) + return; // refuse to send such value in this mode + + while (FULL_BP(outcome_w, outcome_r, N_OUTCOME_BUFFER)) + { + handle_outcome(); + } + + outcome_buffer[outcome_w] = out; + ADVANCE_BP(outcome_w, N_OUTCOME_BUFFER); + + cancel_sleep(WAKEUP_OUTCOME); +} + +void handle_outcome (void) +{ + if (send_xonoff) // requested to send XON or XOFF + { + if (UCSR0A & (1<=0; --i) + { + digit = value % 10; + value /= 10; + + if (digit != 0) + first_digit = i; + + text[i] = digit + '0'; + } + if ((10 - min_digits) < first_digit) + first_digit = 10 - min_digits; + if ((10 - first_digit) > max_digits) + first_digit = 10 - max_digits; + + for (i=first_digit, j=0; i<10; ++i, ++j) + string[j] = text[i]; + + return 10 - first_digit; // return actual number of digits +} + +uint8_t make_hex_string ( // create hexadecimal text representation of number + uint8_t * const string, + uint32_t value, + const uint8_t min_digits, + const uint8_t max_digits, + const uint8_t uppercase +) +{ + int8_t i, j; + uint8_t text[8]; + uint8_t digit; + uint8_t first_digit = 7; + + for(i=7; i>=0; --i) + { + digit = value & 0x0f; + value >>=4; + + if (digit != 0) + first_digit = i; + + if (digit < 10) + text[i] = digit + '0'; + else if (uppercase) + text[i] = digit + 'A' - 10; + else + text[i] = digit + 'a' - 10; + } + if ((8 - min_digits) < first_digit) + first_digit = 8 - min_digits; + if ((8 - first_digit) > max_digits) + first_digit = 8 - max_digits; + + for (i=first_digit, j=0; i<8; ++i, ++j) + string[j] = text[i]; + + return 8 - first_digit; // return actual number of digits +} + +void add_outcome_dec (const uint32_t value, const uint8_t min_digits) +{ + uint8_t text[11]; + uint8_t x; + + x = make_dec_string( + text, + value, + min_digits, + 10 + ); + text[x] = 0x00; + add_outcome_str(text); +} + +void add_outcome_hex (const uint32_t value, const uint8_t min_digits) +{ + uint8_t text[9]; + uint8_t x; + + x = make_hex_string( + text, + value, + min_digits, + 8, + 1 + ); + text[x] = 0x00; + add_outcome_str(text); +} + +uint8_t goto_next_col (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + out_margin |= ignore_margin; + + hpos_aim += cwidth_aim; + if (((hpos_aim + cwidth_aim) > rmargin_aim) && (!out_margin)) + { + stop = 1; + } + + adjust_print_pos(); + return stop; +} + +uint8_t goto_prev_col (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + out_margin |= ignore_margin; + + hpos_aim -= cwidth_aim; + if ((hpos_aim <= lmargin_aim) && (!out_margin)) + { + hpos_aim = lmargin_aim; + stop = 1; + } + adjust_print_pos(); + return stop; +} + +void move_forward_col (const uint8_t n, const uint8_t ignore_margin) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i lwidth) + hpos_aim = lwidth - cwidth_aim; + adjust_print_pos(); +} + +static inline void goto_lmargin (void) +{ + hpos_aim = lmargin_aim; + adjust_print_pos(); +} + +static inline void goto_col0 (void) +{ + out_margin = 1; + hpos_aim = 0; + adjust_print_pos(); +} + +uint8_t goto_next_line (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + vpos_aim += lheight; + + if ( + (((vpos_aim + cwidth) > bmargin) && (!out_margin)) || + ((vpos_aim + cwidth) > pheight) + ) // don't apply +1 offset + stop = 1; + + if (((vpos_aim + lheight) > bmargin ) && (!out_margin)) // don't apply +1 offset + { + // if (vpos <= bmargin) + // vpos_aim = bmargin; // will send us to next page anyways + // else + // vpos_aim = vpos + stop = 1; + } + else if ((vpos_aim + lheight) > pheight) // don't apply +1 offset + { + // if (vpos <= pheight) + // vpos_aim = pheight; + // else + // vpos_aim = pheight + stop = 1; + } + + adjust_print_pos(); + return stop; +} + +uint8_t goto_prev_line (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + vpos_aim -= lheight; + if ((vpos_aim < tmargin ) && (!out_margin))// don't apply -1 offset + { + stop = 1; + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + else if (vpos_aim < 1) + { + stop = 1; + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + + adjust_print_pos(); + return stop; +} + +static inline void goto_next_vstep (void) +{ + ++vpos_aim; + adjust_print_pos(); +} + +static inline void goto_prev_vstep (void) +{ + --vpos_aim; + adjust_print_pos(); +} + +void move_forward_line (const uint8_t n, const uint8_t ignore_margin) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i pheight) // don't apply +1 offset + { + if(vpos <= (pheight - lheight)) + vpos_aim = pheight - lheight; + else + vpos_aim = 0; + } + adjust_print_pos(); +} + +static inline void goto_next_page (void) +{ + out_margin = 1; // will be cancelled anyway + vpos_aim += pheight; + adjust_print_pos(); +} + +static inline void goto_next_page_tmargin (void) +{ + out_margin = 1; // will be cancelled anyway + vpos_aim = tmargin + pheight; + adjust_print_pos(); +} + +static inline void goto_prev_page (void) +{ + out_margin = 1; // will be cancelled anyway [???] + vpos_aim -= pheight; // the world is not ready for this + adjust_print_pos(); +} + +static inline void goto_prev_page_tmargin (void) +{ + out_margin = 1; // will be cancelled anyway [???] + vpos_aim = tmargin - pheight; // the world is not ready for this + adjust_print_pos(); +} + +void move_forward_page (const uint8_t n) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i 0) + { + if (diff > 255) // sorry, too far + return; + move_forward_page(diff); + } + else if (diff < 0) + { + if (diff < -255) // sorry, too far + return; + move_back_page(0-diff); + } +} + +uint8_t is_htab (const int16_t x) +{ + uint8_t i, j; + + if ((x < 0) || (x >= HPOS_LIMIT)) + return 0; + + i = (uint8_t)(x >> 3); + j = ((uint8_t)x) & 7; + + return HTAB[i] & (1<= VPOS_LIMIT)) + return 0; + + i = (uint8_t)(y >> 3); + j = ((uint8_t)y) & 7; + + return VTAB[i] & (1< rmargin_aim) && (!out_margin)) + { + hpos_aim = rmargin_aim; // will send us to next line anyways + stop = 1; + break; + } + else if ((hpos_aim + cwidth) > lwidth) + { + hpos_aim = lwidth - cwidth; + stop = 1; + break; + } + } while (!is_htab(hpos_aim)); + + adjust_print_pos(); + return stop; +} + +uint8_t goto_prev_htab (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + do + { + --hpos_aim; + if ((hpos_aim < lmargin_aim) && (!out_margin)) + { + hpos_aim = lmargin_aim; + stop = 1; + break; + } + else if (hpos_aim < 0) + { + hpos_aim = 0; + stop=1; + break; + } + } while (!is_htab(hpos_aim)); + + adjust_print_pos(); + return stop; +} + +uint8_t goto_next_vtab (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + do + { + ++vpos_aim; + if (((vpos_aim + lheight) > bmargin ) && (!out_margin)) // don't apply +1 offset + { + if (vpos <= bmargin) + vpos_aim = bmargin; // will send us to next page anyways + else + vpos_aim = vpos; + stop = 1; + break; + } + else if ((vpos_aim + lheight) > pheight) // don't apply +1 offset + { + if (vpos <= pheight) + vpos_aim = pheight; + else + vpos_aim = pheight; + stop = 1; + break; + } + } while (!is_vtab(vpos_aim)); + + adjust_print_pos(); + return stop; +} + +uint8_t goto_prev_vtab (const uint8_t ignore_margin) +{ + uint8_t stop = 0; + + out_margin |= ignore_margin; + do + { + --vpos_aim; + if ((vpos_aim < tmargin) && (!out_margin)) // don't apply -1 offset + { + stop = 1; + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + else if (vpos_aim < 0) // don't apply -1 offset + { + stop = -1; + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + } while (!is_vtab(vpos_aim)); + + adjust_print_pos(); + return stop; +} + +void move_forward_htab (const uint8_t n, const uint8_t ignore_margin) +{ + uint8_t i; + + if (n<1) + return; + + for (i=0; i0) + move_forward_htab(x, ignore_margin); + else if (x<0) + move_back_htab(0-x, ignore_margin); +} + +void set_htab (const int16_t x) +{ + uint8_t i, j; + + if ((x < 0) || (x >= HPOS_LIMIT)) + return; + + i = (uint8_t)(x >> 3); + j = ((uint8_t)x) & 7; + + HTAB[i] |= (1<= HPOS_LIMIT)) + return; + + i = (uint8_t)(x >> 3); + j = ((uint8_t)x) & 7; + + HTAB[i] &= ~(1<= VPOS_LIMIT)) + return; + + i = (uint8_t)(y >> 3); + j = ((uint8_t)y) & 7; + + VTAB[i] |= (1<= VPOS_LIMIT)) + return; + + i = (uint8_t)(y >> 3); + j = ((uint8_t)y) & 7; + + VTAB[i] &= ~(1<0; i-=x) + set_htab(i); + for (i=lmargin_aim; i0; i-=y) + set_vtab(i); + for (i=tmargin; i1) + x /= div; + } + else if (mul) + x *= lheight; + else + x *= cwidth_aim; + return x; +} + +void set_lwidth (const uint16_t x) +{ + lwidth = + x; + + // ensure at least 1 character in line & don't exceed limits + if (lwidth < cwidth_aim) + lwidth = cwidth_aim; + if (lwidth > HPOS_LIMIT) + lwidth = HPOS_LIMIT; + if(rmargin_aim > lwidth) + rmargin_aim = lwidth; + if(lmargin_aim > (rmargin_aim - cwidth_aim)) + lmargin_aim = rmargin_aim - cwidth_aim; +} + +void set_pheight (const uint16_t y) +{ + pheight = y; + + // ensure at least 1 line in page & don't exceed limits + if (pheight < lheight) + pheight = lheight; + if (pheight > VPOS_LIMIT) + pheight = VPOS_LIMIT; + if (bmargin > pheight) + bmargin = pheight; + if(tmargin > bmargin - lheight) + tmargin = bmargin - lheight; +} + +void set_cwidth (const uint8_t x) +{ + cwidth_aim = x; + + // ensure at least 1 character in line + if (lwidth < cwidth_aim) + lwidth = cwidth_aim; + if (lmargin + cwidth_aim > lwidth) + lmargin = lwidth - cwidth_aim; + if (lmargin + cwidth_aim > rmargin_aim) + rmargin_aim = lmargin_aim + cwidth_aim; + + if(hpos == lmargin) // opportunity to adjust at machine + { + if (x == WIDTH_10) + { + if (cwidth != WIDTH_10) + add_print_key(CODE_PITCH10); + cwidth = WIDTH_10; + } + else + { + if (cwidth != WIDTH_12) + add_print_key(CODE_PITCH12); + cwidth = WIDTH_12; + } + cwidth_todo = 0; + } + else + cwidth_todo = 1; +} + +void set_lheight (const uint8_t y) +{ + lheight = y; + + // ensure at least 1 line in page + if (pheight < lheight) + pheight = lheight; + if (tmargin + lheight > pheight) + tmargin = pheight - lheight; + if (tmargin + lheight > bmargin) + bmargin = tmargin + lheight; +} + +void set_lmargin (int16_t x) +{ + if (x<0) + x = 0; + lmargin_aim = x; + if ((lmargin_aim + cwidth_aim) > HPOS_LIMIT) + lmargin_aim = HPOS_LIMIT - cwidth_aim; + if ((lmargin_aim + cwidth_aim) > lwidth) + lwidth = lmargin_aim + cwidth_aim; + if ((lmargin_aim + cwidth_aim) > rmargin_aim) + rmargin_aim = lmargin_aim + cwidth_aim; +} + +void set_rmargin (int16_t x) +{ + if (x<0) + x = 0; + rmargin_aim = x; + if (rmargin_aim < cwidth_aim) + rmargin_aim = cwidth_aim; + if (rmargin_aim > HPOS_LIMIT) + rmargin_aim = HPOS_LIMIT; + if (rmargin_aim > lwidth) + lwidth = rmargin_aim; + if((lmargin_aim + cwidth_aim) > rmargin_aim) + lmargin_aim = rmargin_aim - cwidth_aim; +} + +static inline void set_lmargin_ch (uint8_t x) +{ + if(x==0xFF) + x = 0; + set_lmargin(cwidth_aim * (int16_t)x); +} + +static inline void set_rmargin_ch (uint8_t x) +{ + if(x==0xFF) + x = 0; + set_rmargin(cwidth_aim * (int16_t)x); +} + +void set_rmargin_rel (const int16_t x) +{ + if (x>0) + set_rmargin(lmargin_aim + x); // relative to left margin + else + set_rmargin(lwidth + x); // relative to rigth edge +} + +void set_tmargin (int16_t y) +{ + if (y<0) + y = 0; + tmargin = y; + if ((tmargin + lheight) > VPOS_LIMIT) + tmargin = VPOS_LIMIT - lheight; + if ((tmargin + lheight) > pheight) + pheight = tmargin + lheight; + if ((tmargin + lheight) > bmargin) + bmargin = tmargin + lheight; +} + +void set_bmargin (int16_t y) +{ + if (y<0) + y = 0; + bmargin = y; + if (bmargin < lheight) + bmargin = lheight; + if (bmargin > VPOS_LIMIT) + bmargin = VPOS_LIMIT; + if (bmargin > pheight) + pheight = bmargin; + if ((tmargin + lheight) > bmargin) + { + tmargin = bmargin - lheight; + } +} + +static inline void set_tmargin_ch (uint8_t y) +{ + if(y==0xFF) + y = 0; + set_tmargin(lheight * (int16_t)y); +} + +static inline void set_bmargin_ch (uint8_t y) +{ + if(y==0xFF) + y = 0; + set_bmargin(lheight * (int16_t)y); +} + +void set_bmargin_rel (const int16_t y) +{ + if (y>0) + set_bmargin(tmargin + y); // relative to top margin + else + set_bmargin(pheight + y); // relative to bottom edge +} + +void set_style (const uint8_t new_style) +{ + if ( // set bold + (new_style & STYLE_BOLD) && + (!(style & STYLE_BOLD)) + ) + add_print_key(CODE_BOLD); + else if ( // clear bold + (!(new_style & STYLE_BOLD)) && + (style & STYLE_BOLD) + ) + add_print_key(CODE_BOLD); + + // if ( // set underline + // (new_style & STYLE_UNDER) && + // (!(style & STYLE_UNDER)) + // ) + // add_print_key(CODE_UNDER); + // else if ( // clear underline + // (!(new_style & STYLE_UNDER)) && + // (style & STYLE_UNDER) + // ) + // add_print_key(CODE_UNDER); + + if ( // set strong + (new_style & STYLE_STRONG) && + (!(style & STYLE_STRONG)) + ) + add_print_key(CODE_STRONG); + else if ( // clear strong + (!(new_style & STYLE_STRONG)) && + (style & STYLE_STRONG) + ) + add_print_key(CODE_WEAK); + + style = new_style; +} + +static inline void set_style_normal (void) +{ + set_style((style & ~STYLE_STRONG) | STYLE_NORMAL); +} + +static inline void set_style_bold (void) +{ + set_style(style | STYLE_BOLD); +} + +static inline void set_style_nobold (void) +{ + set_style(style & ~STYLE_BOLD); +} + +static inline void toggle_bold (void) +{ + set_style(style ^ STYLE_BOLD); +} + +static inline void set_style_under (void) +{ + set_style((style & ~STYLE_UNDER2) | STYLE_UNDER); +} + +static inline void set_style_under2 (void) +{ + set_style((style & ~STYLE_UNDER) | STYLE_UNDER2); +} + +static inline void set_style_nounder (void) +{ + set_style(style & ~(STYLE_UNDER | STYLE_UNDER2)); +} + +static void inline toggle_under (void) +{ + if (style & (STYLE_UNDER | STYLE_UNDER2)) + set_style_nounder(); + else + set_style_under(); +} + +static inline void set_style_cross (void) +{ + set_style(style | STYLE_CROSS); +} + +static inline void set_style_nocross (void) +{ + set_style(style & ~STYLE_CROSS); +} + +static inline void set_style_over (void) +{ + set_style(style | STYLE_OVER); +} + +static inline void set_style_noover (void) +{ + set_style(style & ~STYLE_OVER); +} + +static inline void set_style_strong (void) +{ + set_style(style | STYLE_STRONG); +} + +static inline void set_style_weak (void) +{ + set_style(style & ~STYLE_STRONG); +} + +void add_print_key (const uint8_t key) +{ + while (FULL_BP(print_w, print_r, N_PRINT_BUFFER)) + { + } + print_buffer[print_w] = key; + ADVANCE_BP(print_w, N_PRINT_BUFFER); +} + +void adjust_print_pos (void) +{ + // dest. inside margins; cancel the privilege + if ( + (hpos_aim >= lmargin_aim) && + ((hpos_aim + cwidth_aim) <= rmargin_aim) && + (vpos_aim >= tmargin - 1) && + ((vpos_aim + lheight) <= (bmargin + 1)) + ) + out_margin = 0; + + // outside current margins; adjust margins + if ((hpos > rmargin) && (hpos <= rmargin_aim)) + { + add_print_key(CODE_RMARGIN); + rmargin = hpos; + } + if ((hpos < lmargin) && (hpos >= lmargin_aim)) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + else if ((hpos == lmargin_aim) && (lmargin != lmargin_aim)) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + + // requested move outside right margin + if ((hpos_aim + cwidth_aim) > rmargin_aim) + { + // not allowed to leave; goto next line + if (!out_margin) + { + hpos_aim = lmargin_aim; + vpos_aim += lheight; + } + // requested move outside right edge; stay at edge + else if ((hpos_aim + cwidth_aim) > lwidth) + { + hpos_aim = lwidth - cwidth_aim; + } + } + + // requested move outside left margin + if (hpos_aim < lmargin_aim) + { + // not allowed to leave; stay at margin + if (!out_margin) + hpos_aim = lmargin_aim; + // requested move outside left edge; stay at edge + else if (hpos_aim < 0) + hpos_aim = 0; + } + + // requested move outside bottom margin; wait for new page + if ((vpos_aim + lheight) > (bmargin + 1)) + { + if (!out_margin ) // not allowed to leave + { + if (vpos_aim < pheight + tmargin) + vpos_aim = pheight + tmargin; // skip to next page top margin + set_alarm = 1; + set_led = 10; + wait_page = 1; + } + else if ((vpos_aim + lheight) > (pheight + 1)) // requested move outside bottom edge + { + set_alarm = 1; + set_led = 10; + wait_page = 1; + } + } + + // requested move outside top margin + if (vpos_aim < (tmargin - 1)) + { + // not allowed to leave; stay at top margin + if (!out_margin) + { + if (vpos >= tmargin) + vpos_aim = tmargin; + else + vpos_aim = vpos; + } + // requested move outside top edge; stay at edge + else if (vpos_aim < -1) + { + if (vpos >= 0) + vpos_aim = 0; + else + vpos_aim = vpos; + } + } + + // left from goal; move right + while (hpos < hpos_aim) + { + // move outside margin + if (hpos + cwidth > rmargin) + add_print_key(KEY_MARGIN); + + // move right by 1 space + add_print_key(KEY_SPACE); + hpos += cwidth; + + // outside margin; adjust margin + if (hpos > rmargin) + { + add_print_key(CODE_RMARGIN); + rmargin = hpos; + } + } + + // right from goal & from left margin; move to left margin + if ((hpos_aim <= lmargin) && (hpos > lmargin)) + { + add_print_key(CODE_RETURN); + hpos = lmargin; + } + + // right from goal; move left + while (hpos > hpos_aim) + { + // away by at least 1 space + if (hpos >= hpos_aim + cwidth) + { + // move outside margin + if (hpos < lmargin + cwidth) + add_print_key(KEY_MARGIN); + + // move left by 1 space + add_print_key(KEY_BACK); + hpos -= cwidth; + } + // away by less than 1 space + else + { + // move outside margin + if (hpos < lmargin + 1) + add_print_key(KEY_MARGIN); + + // move left by 1 unit + add_print_key(CODE_STEPLEFT); + --hpos; + } + + // outside margin; adjust margin + if(hpos < lmargin) + { + add_print_key(CODE_LMARGIN); + lmargin = hpos; + } + } + + // above goal; move down + while (vpos < vpos_aim) + { + add_print_key(CODE_HALFDOWN); + ++vpos; + } + + // below goal; move up + while (vpos > vpos_aim) + { + add_print_key(CODE_HALFUP); + --vpos; + } + + // next char will be out of margin + if (hpos + cwidth > rmargin) + add_print_key(KEY_MARGIN); + + // out of page; renormalise coordinates + while (vpos_aim < -1) + { + vpos_aim += pheight; + vpos += pheight; + --ppos; + } + while ((vpos_aim + lheight) > (pheight + 1)) + { + vpos_aim -= pheight; + vpos -= pheight; + ++ppos; + } + + // opportunity to adjust char width + if (cwidth_todo & (hpos == lmargin)) + set_cwidth(cwidth_aim); +} + +void add_print_ch (uint8_t const * const ch) +{ + uint8_t const * p; + uint8_t count; + + // prepare position before + // often redundant but not always + adjust_print_pos(); + + p = ch; + + // replacement symbol for unknown char + if (p == CH_UNKN) + p = REPLACE[replace]; + + // nothing to print + if (*p == 0) + return; + + // add key sequence to buffer + for (count = *p; count!=0; --count) + { + ++p; + add_print_key(*p); + } + + // manually apply styles not handled automatically + if (style & STYLE_UNDER) + { + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + } + if (style & (STYLE_CROSS|STYLE_OVER)) + { + add_print_key(CODE_HALFUP); + if (style & STYLE_CROSS) + { + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + } + if (style & STYLE_OVER) + { + add_print_key(CODE_HALFUP); + add_print_key(KEY_BACK); + add_print_key(SKEY_UNDER); + add_print_key(CODE_HALFDOWN); + } + add_print_key(CODE_HALFDOWN); + } + if (style & STYLE_UNDER2) + { + add_print_key(CODE_HALFDOWN); + add_print_key(KEY_BACK); + add_print_key(SKEY_EQ); + add_print_key(CODE_HALFUP); + } + + // adjust position + hpos += cwidth; + hpos_aim += cwidth_aim; + + // moved out of line; adjust again + if ((hpos_aim + cwidth_aim) > rmargin_aim) + adjust_print_pos(); +} + +static inline void handle_print (void) +{ + static uint8_t phase=0; + static uint8_t count=0; + static uint8_t delay=255; + static uint8_t alarm=0; + + uint8_t key; + + if (set_alarm) + { + if (set_alarm > alarm) + alarm = set_alarm; + set_alarm = 0; + } + + if (!phase) // free to print next key + { + if (delay || alarm) + { + if (alarm) + { + PORT_KEY = CODE_BELL; + phase = 3; + --alarm; + } + if (delay) + --delay; + } + else if (!(mode & MODE_TERM)) + { + } + else if (NOT_EMPTY_BP(print_w, print_r, N_PRINT_BUFFER)) + { + key = print_buffer[print_r]; + ADVANCE_BP(print_r, N_PRINT_BUFFER); + + if ((key == CODE_STEPLEFT_EXTRA) && (cwidth == WIDTH_NORMAL)) + { + } + else + { + PORT_KEY = key; + phase = 3; + + switch (key) + { + case CODE_RETURN: + case KEY_RETURN: + delay = count; + count = 0; + break; + case KEY_BACK: + if (count >= PRINT_DELAY) + count -= PRINT_DELAY; + else + count = 0; + break; + default: + if (count < 0xff - PRINT_DELAY) + count += PRINT_DELAY; + else + count = 0xff; + switch(key) + { + case CODE_STEPLEFT: + case CODE_STEPLEFT_EXTRA: + // case KEY_SPACE: + // case KEY_BACK: + case CODE_HALFUP: + // case CODE_HALFDOWN: + phase += 2; + } + + // if (style & STYLE_UNDER) + // ++phase; + if (style & STYLE_BOLD) + ++phase; + } + } + } + } + else + { + if (phase == 3) // key down + PORT_CTRL &= ~KEY; + else if (phase == 1) // key up + PORT_CTRL |= KEY; + --phase; + } +} + +ISR(USART0_RX_vect) +{ + uint8_t in, err; + + err = UCSR0A & ((1 << FE0) | (1 << UPE0)); + in = UDR0; // get the byte + + if (err) + return; + + if ((flow & FLOW_SW) == FLOW_XONOFF) + { + if ((in == XON) || (in == XOFF)) + { + remote_xonoff = in; + return; + } + } + + if (!income_requested()) + return; + + + add_income(in, 0); +} + +uint8_t handle_ctrl (uint8_t in) +{ + static uint8_t ind = 0; + static uint8_t buffer[N_ESC_BUFFER]; + static uint8_t prev = 0; + static uint8_t ib = 0; + + uint16_t long_id; + + uint8_t c1_allowed = c1; + + uint8_t handled = 0; + + uint8_t * buffer_pos = buffer; + uint8_t p_ind = 0; + uint8_t sp_ind = 0; + + // temporary for storing parameters + uint8_t u0; + + if (esc_mode == ESC_ECMA_48) + { + if (prev == 0x1B) // ESC - ESCAPE + { + if ((in >= 0x40) && (in <= 0x5F)) // C1 recode + { + in += 0x40; + c1_allowed = 1; + if (ind) + --ind; + } + else // delayed reaction; interrupt previous sequence, start new + { + if (buffer[0] != 0x98) // SOS + { + buffer[0] = 0x1B; + ib = 0; + ind = 1; + } + } + } + + // C0, C1, GR not allowed inside sequences unless in control string + if ( + ((in < 0x20) || (in > 0x7E)) && // char out of GL + (ind != 0x1B) && // but not ESC (deal with it in next iteration) + ind // in sequence already + ) + { + switch(buffer[0]) + { + case 0x98: // SOS + break; + case 0x90: // DCS + case 0x9A: // SCI + case 0x9D: // OSC + case 0x9E: // PM + case 0x9F: // APC + if (((in >= 0x08) && (in <= 0x0C)) || (in == 0x9C)) // allowed; do nothing + break; + default: + ind = 0; + break; + } + } + } + + if (ind < N_ESC_BUFFER) + buffer[ind] = in; + + if (!ind) // single character or new sequence + { + if ((in <= 0x1F) || (in == 0x7F)) // C0 + { + switch (in) + { + case 0x00: // NUL - NULL + break; + // case 0x01: // SOH - START OF HEADING + // case 0x02: // STX - START OF TEXT + // case 0x03: // ETX - END OF TEXT + // case 0x04: // EOT - END OF TRANSMISSION + // case 0x05: // ENQ - ENQUIRY + // case 0x06: // ACK - ACKNOWLEDGE + case 0x07: // BEL - BELL + add_print_key (CODE_BELL); + break; + case 0x08: // BS - BACKSPACE + case 0x7F: // DEL - DELETE // TODO: should I accept this here? + goto_prev_col(0); + break; + case 0x09: // HT - CHARACTER TABULATION + goto_next_htab(0); + break; + case 0x0A: // LF - LINE FEED + if (nl_mode & NL_IMPLICIT_CR) + goto_lmargin(); + if (!((nl_mode & NL_IMPLICIT_LF) && (prev==0x0D))) // already handled in last step? + goto_next_line(0); + break; + case 0x0B: // VT - LINE TABULATION + goto_next_vtab(0); + break; + case 0x0C: // FF - FORM FEED + goto_next_page_tmargin(); + break; + case 0x0D: // CR - CARRIAGE RETURN + goto_lmargin(); + if (nl_mode & NL_IMPLICIT_LF) + goto_next_line(0); + break; + // case 0x0E: // SO - SHIFT-OUT + // case 0x0F: // SI - SHIFT-IN + // case 0x10: // DLE - DATA LINK ESCAPE + // case 0x11: // DC1 - DEVICE CONTROL ONE + // case 0x12: // DC2 - DEVICE CONTROL TWO + // case 0x13: // DC3 - DEVICE CONTROL THREE + // case 0x14: // DC4 - DEVICE CONTROL FOUR + // case 0x15: // NAK - NEGATIVE ACKNOWLEDGE + // case 0x16: // SYN - SYNCHRONOUS IDLE + // case 0x17: // ETB - END OF TRANSMISSION BLOCK + // case 0x18: // CAN - CANCEL + // case 0x19: // EM - END OF MEDIUM + // case 0x1A: // SUB - SUBSTITUTE + case 0x1B: // ESC - ESCAPE + if (esc_mode == ESC_ECMA_48) + { + ++ind; // start sequence + ib = 0; // reset intermediate byte count + } + // else if (esc_mode == ESC_P_POS) + // ++ind; + break; + // case 0x1C: // IS4 - INFORMATION SEPARATOR FOUR + // case 0x1D: // IS3 - INFORMATION SEPARATOR THREE + // case 0x1E: // IS2 - INFORMATION SEPARATOR TWO + // case 0x1F: // IS1 - INFORMATION SEPARATOR ONE + default: + if (esc_mode == ESC_NONE) + { + add_print_ch(CH_ASCII['^']); + add_print_ch(CH_ASCII['@'+in]); + } + break; + } + handled = 1; + } + else if ((in >= 0x80) && (in <= 0x9F) && c1_allowed) // C1 + { + if (esc_mode == ESC_ECMA_48) + { + switch (in) + { + //case 0x80: // 1B 40 reserved + //case 0x81: // 1B 41 reserved + //case 0x82: // 1B 42 BPH - BREAK PERMITTED HERE + //case 0x83: // 1B 43 NBH - NO BREAK HERE + //case 0x84: // 1B 44 reserved + case 0x85: // 1B 45 NEL - NEXT LINE + goto_lmargin(); + goto_next_line(0); + break; + //case 0x86: // 1B 46 SSA - START OF SELECTED AREA + //case 0x87: // 1B 47 ESA - END OF SELECTED AREA + case 0x88: // 1B 48 HTS - CHARACTER TABULATION SET + set_htab(hpos_aim); + break; + case 0x89: // 1B 49 HTJ - CHARACTER TABULATION WITH JUSTIFICATION + goto_next_htab(0); + break; + case 0x8A: // 1B 4A VTS - LINE TABULATION SET + set_vtab(vpos_aim); + break; + case 0x8B: // 1B 4B PLD - PARTIAL LINE FORWARD + goto_next_vstep(); + break; + case 0x8C: // 1B 4C PLU - PARTIAL LINE BACKWARD + goto_prev_vstep(); + break; + case 0x8D: // 1B 4D RI - REVERSE LINE FEED + goto_prev_line(0); + break; + //case 0x8E: // 1B 4E SS2 - SINGLE-SHIFT TWO + //case 0x8F: // 1B 4F SS3 - SINGLE-SHIFT THREE + //case 0x91: // 1B 51 PU1 - PRIVATE USE ONE + //case 0x92: // 1B 52 PU2 - PRIVATE USE TWO + //case 0x93: // 1B 53 STS - SET TRANSMIT STATE + //case 0x94: // 1B 54 CCH - CANCEL CHARACTER + //case 0x95: // 1B 55 MW - MESSAGE WAITING (TODO: ->DSR) + //case 0x96: // 1B 56 SPA - START OF GUARDED AREA + //case 0x97: // 1B 57 EPA - END OF GUARDED AREA + //case 0x99: // 1B 59 reserved + //case 0x9C: // 1B 5C ST - STRING TERMINATOR + + // control string / control sequence: + + case 0x90: // 1B 50 DCS 08-0C,20-7E - DEVICE CONTROL STRING + case 0x98: // 1B 58 SOS any - START OF STRING + case 0x9A: // 1B 5A SCI 08-0C,20-7E - SINGLE CHARACTER INTRODUCER + case 0x9D: // 1B 5D OSC 08-0C,20-7E - OPERATING SYSTEM COMMAND + case 0x9E: // 1B 5E PM 08-0C,20-7E - PRIVACY MESSAGE + case 0x9F: // 1B 5F APC 08-0C,20-7E - APPLICATION PROGRAM COMMAND + case 0x9B: // 1B 5B CSI - CONTROL SEQUENCE INTRODUCER + ++ind; + ib = 0; + break; + } + handled = 1; + } + else + handled = 0; + } + else // normal text + handled = 0; + } + else // continued sequence + { + if (esc_mode == ESC_ECMA_48) + { + handled = 1; + + if (in == 0x1B) // ESC - ESCAPE + { + // allow to go through. We'll deal with it next iteration. + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else + { + switch (buffer[0]) + { + case 0x1B: // ESC - ESCAPE + if ((buffer[1] >= 0x20) && (buffer[1] <= 0x2F)) // nF + { + if ((in >= 0x20) && (in <= 0x2F)) // intermediate byte + { + ++ib; // count intermediate bytes + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else if ((in >= 0x30) && (in <= 0x7E)) // final byte + { + switch (buffer[1]) + { + // case 0x20: // ANNOUNCE CODE STRUCTURE + // case 0x21: // C0-DESIGNATE + // case 0x22: // C1-DESIGNATE + // case 0x23: // Single control functions + // case 0x24: // Designation of multiple-byte graphic character sets + case 0x25: // DESIGNATE OTHER CODING SYSTEM + if (ib == 1) + long_id = buffer[1]; + else if (ib == 2) + long_id = (((uint16_t)buffer[1])<<8) | buffer[2]; + else + break; + switch (long_id) + { + case 0x47: + case 0x2f47: + case 0x2f48: + case 0x2f49: + set_encoding(encoding | ENC_UNI); + break; + case 0x40: + set_encoding_GR(GR_index); + break; + } + break; + // case 0x26: // IDENTIFY REVISED REGISTRATION + // case 0x27: // (reserved for future standardisation) + // case 0x28: // G0-DESIGNATE 94-SET + // case 0x29: // G1-DESIGNATE 94-SET + // case 0x2A: // G2-DESIGNATE 94-SET + // case 0x2B: // G3-DESIGNATE 94-SET + // case 0x2C: // (reserved for future standardisation) + case 0x2D: // G1-DESIGNATE 96-SET + case 0x2E: // G2-DESIGNATE 96-SET + case 0x2F: // G3-DESIGNATE 96-SET + u0 = buffer[1] - 0x2D + 1; + if (ib == 1) // single intermediate byte + { + switch (buffer[2]) // final byte + { + case 0x41: + case 0x63: + GR_table[u0] = ENC_ISO8859_1; + break; + case 0x42: + GR_table[u0] = ENC_ISO8859_2; + break; + // case 0x43: + // GR_table[u0] = ENC_ISO8859_3; + // break; + // case 0x44: + // case 0x64: + // GR_table[u0] = ENC_ISO8859_4; + // break; + // case 0x4D: + // GR_table[u0] = ENC_ISO8859_9; + // break; + // case 0x56: + // GR_table[u0] = ENC_ISO8859_10; + // break; + // case 0x65: + // GR_table[u0] = ENC_ISO8859_13; + // break; + // case 0x62: + // GR_table[u0] = ENC_ISO8859_15; + // break; + default: + u0 = 0xff; + } + if (u0 == GR_index) + set_encoding_GR(GR_index); + } + break; + } + ind = 0; + } + else // invalid value + { + ind = 0; + handled = 0; + } + } + else if ((buffer[1] >= 0x30) && (buffer[1] <= 0x7E)) // Fp, Fs, control function + { + switch(buffer[1]) + { + // case 0x60: // DMI - DISABLE MANUAL INPUT + // case 0x61: // INT - INTERRUPT + // case 0x62: // EMI - ENABLE MANUAL INPUT + case 0x63: // RIS - RESET TO INITIAL STATE + out_margin = 0; + + pheight = DEFAULT_PHEIGHT; + tmargin = DEFAULT_TMARGIN; + bmargin = DEFAULT_BMARGIN; + lheight = HEIGHT_NORMAL; + theight_ch = DEFAULT_THEIGHT_CH; + + lwidth = DEFAULT_LWIDTH; + lmargin_aim = DEFAULT_LMARGIN_AIM; + rmargin_aim = DEFAULT_RMARGIN_AIM; + cwidth_aim = WIDTH_NORMAL; + twidth_ch = DEFAULT_TWIDTH_CH; + + set_style_normal(); + + load_config(); + + ppos = -1; + vpos_aim = pheight + tmargin; + hpos_aim = lmargin_aim; + adjust_print_pos(); + break; + // case 0x64: // CMD - CODING METHOD DELIMITER + // case 0x6E: // LS2 - LOCKING-SHIFT TWO + // case 0x6F: // LS3 - LOCKING-SHIFT THREE + case 0x7C: // LS3R - LOCKING-SHIFT THREE RIGHT + set_encoding_GR(3); + break; + case 0x7D: // LS2R - LOCKING-SHIFT TWO RIGHT + set_encoding_GR(2); + break; + case 0x7E: // LS1R - LOCKING-SHIFT ONE RIGHT + set_encoding_GR(1); + break; + default: + break; + } + ind = 0; + } + else // invalid value + { + ind = 0; + handled = 0; + } + break; + case 0x9B: // 1B 5B CSI - CONTROL SEQUENCE INTRODUCER + if ((in >= 0x30) && (in <= 0x3F)) // parameter byte + { + if (prev < 0x30) // I before P + { + ind = 0; + handled = 0; + } + else // ok + { + if (ind < N_ESC_BUFFER-1) + ++ind; + } + } + else if ((in >= 0x20) && (in <= 0x2F)) // intermediate byte + { + ++ib; // count intermediate bytes + if (ind < N_ESC_BUFFER-1) + ++ind; + } + else if ((in >= 0x40) && (in <= 0x7E)) // final byte + { + buffer_pos = buffer + 1; + if (ib == 0) // just 1 final byte + long_id = in; + else if (ib == 1) // 1 intermediate & 1 final byte + long_id = (((uint16_t)prev)<<8)|in; + else + long_id =0; + switch (long_id) + { + // case 0x40: // ICH - INSERT CHARACTER + case 0x41: // CUU - CURSOR UP + case 0x6B: // VPB - LINE POSITION BACKWARD + move_back_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x42: // CUD - CURSOR DOWN + case 0x65: // VPR - LINE POSITION FORWARD + move_forward_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x43: // CUF - CURSOR RIGHT + case 0x61: // HPR - CHARACTER POSITION FORWARD + move_forward_col((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x44: // CUB - CURSOR LEFT + case 0x6A: // HPB - CHARACTER POSITION BACKWARD + move_back_col((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x45: // CNL - CURSOR NEXT LINE + goto_col0(); + move_forward_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x46: // CPL - CURSOR PRECEDING LINE + goto_col0(); + move_back_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x47: // CHA - CURSOR CHARACTER ABSOLUTE + case 0x60: // HPA - CHARACTER POSITION ABSOLUTE + goto_col(((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1))-1); + break; + case 0x48: // CUP - CURSOR POSITION + case 0x66: // HVP - CHARACTER AND LINE POSITION + goto_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + goto_col((uint8_t)get_ctrl_parameter(CTRL_IND, 1, 0, 1)-1); + break; + case 0x49: // CHT - CURSOR FORWARD TABULATION + move_forward_htab ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x4A: // ED - ERASE IN PAGE + // case 0x4B: // EL - ERASE IN LINE + // case 0x4C: // IL - INSERT LINE + // case 0x4D: // DL - DELETE LINE + // case 0x4E: // EF - ERASE IN FIELD + // case 0x4F: // EA - ERASE IN AREA + // case 0x50: // DCH - DELETE CHARACTER + // case 0x51: // SEE - SELECT EDITING EXTENT + // case 0x52: // CPR - ACTIVE POSITION REPORT + // case 0x53: // SU - SCROLL UP + // case 0x54: // SD - SCROLL DOWN + case 0x55: // NP - NEXT PAGE + move_forward_page_tmargin((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x56: // PP - PRECEDING PAGE + move_back_page_tmargin((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x57: // CTC - CURSOR TABULATION CONTROL + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + set_htab(hpos_aim); + break; + case 1: + set_vtab(vpos_aim); + break; + case 2: + clear_htab(hpos_aim); + break; + case 3: + clear_vtab(hpos_aim); + break; + case 4: + case 5: + clear_htab_all(); + break; + case 6: + clear_vtab_all(); + break; + } + break; + // case 0x58: // ECH - ERASE CHARACTER + case 0x59: // CVT - CURSOR LINE TABULATION + move_forward_vtab((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + case 0x5A: // CBT - CURSOR BACKWARD TABULATION + move_back_htab ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x5B: // SRS - START REVERSED STRING + // case 0x5C: // PTX - PARALLEL TEXTS + // case 0x5D: // SDS - START DIRECTED STRING + // case 0x5E: // SIMD - SELECT IMPLICIT MOVEMENT DIRECTION + // case 0x62: // REP - REPEAT // TODO:??? + // case 0x63: // DA - DEVICE ATTRIBUTES + case 0x64: // VPA - LINE POSITION ABSOLUTE + goto_line((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x67: // TBC - TABULATION CLEAR + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + clear_htab(hpos_aim); + break; + case 1: + clear_vtab(vpos_aim); + break; + case 2: + case 3: + clear_htab_all(); + break; + case 5: + clear_htab_all(); + case 4: + clear_vtab_all(); + break; + } + break; + // case 0x68: // SM - SET MODE + // case 0x69: // MC - MEDIA COPY + // case 0x6C: // RM - RESET MODE + case 0x6D: // SGR - SELECT GRAPHIC RENDITION + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + case 65: + set_style_normal(); + break; + case 1: + set_style_bold(); + break; + case 4: + set_style_under(); + break; + case 9: + set_style_cross(); + break; + case 21: + set_style_under2(); + break; + case 22: + set_style_nobold(); + break; + case 24: + set_style_nounder(); + break; + case 29: + set_style_nocross(); + break; + case 53: + set_style_over(); + break; + case 55: + set_style_noover(); + break; + } + break; + case 0x6E: // DSR - DEVICE STATUS REPORT + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + //case 0: + //case 1: + //case 2: + //case 3: + //case 4: + case 5: + //TODO: send DSR here + break; + case 6: + //TODO: send CPR here + break; + } + break; + // case 0x6F: // DAQ - DEFINE AREA QUALIFICATION + + // case 0x2040: // SL - SCROLL LEFT + // case 0x2041: // SR - SCROLL RIGHT + // case 0x2043: // GSS - GRAPHIC SIZE SELECTION + // set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + // // width is implicit, but I don't change it here + // break; + // case 0x2044: // FNT - FONT SELECTION + // case 0x2045: // TSS - THIN SPACE SPECIFICATION + // case 0x2046: // JFY - JUSTIFY + case 0x2047: // SPI - SPACING INCREMENT + set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + set_cwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 1, 0, 0))); + break; + // case 0x2048: // QUAD - QUAD + case 0x2049: // SSU - SELECT SIZE UNIT + switch ((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: // CHARACTER + hunit_mul = HUNIT_MUL_CH; + hunit_div = HUNIT_DIV_CH; + vunit_mul = VUNIT_MUL_CH; + vunit_div = VUNIT_DIV_CH; + break; + case 1: // MILLIMETRE + hunit_mul = HUNIT_MUL_MM; + hunit_div = HUNIT_DIV_MM; + vunit_mul = VUNIT_MUL_MM; + vunit_div = VUNIT_DIV_MM; + break; + case 2: // COMPUTER DECIPOINT + hunit_mul = HUNIT_MUL_CDP; + hunit_div = HUNIT_DIV_CDP; + vunit_mul = VUNIT_MUL_CDP; + vunit_div = VUNIT_DIV_CDP; + break; + case 3: // DECIDIDOT + hunit_mul = HUNIT_MUL_DD; + hunit_div = HUNIT_DIV_DD; + vunit_mul = VUNIT_MUL_DD; + vunit_div = VUNIT_DIV_DD; + break; + case 4: // MIL + hunit_mul = HUNIT_MUL_MIL; + hunit_div = HUNIT_DIV_MIL; + vunit_mul = VUNIT_MUL_MIL; + vunit_div = VUNIT_DIV_MIL; + break; + case 5: // BASIC MEASURING UNIT + hunit_mul = HUNIT_MUL_BMU; + hunit_div = HUNIT_DIV_BMU; + vunit_mul = VUNIT_MUL_BMU; + vunit_div = VUNIT_DIV_BMU; + break; + case 6: // MICROMETRE + hunit_mul = HUNIT_MUL_UM; + hunit_div = HUNIT_DIV_UM; + vunit_mul = VUNIT_MUL_UM; + vunit_div = VUNIT_DIV_UM; + break; + case 7: // PIXEL + hunit_mul = 1; + hunit_div = 1; + vunit_mul = 1; + vunit_div = 1; + break; + case 8: // DECIPOINT + hunit_mul = HUNIT_MUL_DP; + hunit_div = HUNIT_DIV_DP; + vunit_mul = VUNIT_MUL_DP; + vunit_div = VUNIT_DIV_DP; + break; + } + break; + case 0x204A: // PFS - PAGE FORMAT SELECTION + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_PF) + { + set_pheight(PHEIGHT_PRESET[u0]); + set_tmargin(0); + set_bmargin_rel(0); + set_theight_ch(theight_ch); + set_lwidth(LWIDTH_PRESET[u0]); + set_lmargin(LMARGIN_PRESET); + set_rmargin_rel(0-RMARGIN_PRESET); + set_twidth_ch(twidth_ch); + adjust_print_pos(); + // TODO: new page? + } + break; + case 0x204B: // SHS - SELECT CHARACTER SPACING + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_CWIDTH) + set_cwidth(CWIDTH_PRESET[u0]); + break; + case 0x204C: // SVS - SELECT LINE SPACING + u0 = (uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0); + if (u0 < N_LHEIGHT) + set_lheight(LHEIGHT_PRESET[u0]); + break; + // case 0x204D: // IGS - IDENTIFY GRAPHIC SUBREPERTOIRE + // case 0x204F: // IDCS - IDENTIFY DEVICE CONTROL STRING + case 0x2050: // PPA - PAGE POSITION ABSOLUTE + goto_page((int16_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x2051: // PPR - PAGE POSITION FORWARD + move_forward_page((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + case 0x2052: // PPB - PAGE POSITION BACKWARD + move_back_page((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + // case 0x2053: // SPD - SELECT PRESENTATION DIRECTIONS + case 0x2054: // DTA - DIMENSION TEXT AREA + set_pheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + set_lwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 1, 0, 0))); + adjust_print_pos(); + // TODO: set new margins? + break; + case 0x2055: // SLH - SET LINE HOME + set_lmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x2056: // SLL - SET LINE LIMIT + set_rmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)); + break; + // case 0x2057: // FNK - FUNCTION KEY + // case 0x2058: // SPQR - SELECT PRINT QUALITY AND RAPIDITY + case 0x2059: // SEF - SHEET EJECT AND FEED + // partial implementation: move out of page + goto_next_page_tmargin(); + break; + case 0x205A: // PEC - PRESENTATION EXPAND OR CONTRACT + switch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)) + { + case 0: + set_cwidth(WIDTH_NORMAL); + break; + case 1: + set_cwidth(WIDTH_WIDE); + break; + case 2: + set_cwidth(WIDTH_NARROW); + break; + } + break; + // case 0x205B: // SSW - SET SPACE WIDTH + // case 0x205C: // SACS - SET ADDITIONAL CHARACTER SEPARATION + // case 0x205D: // SAPV - SELECT ALTERNATIVE PRESENTATION VARIANTS + case 0x205E: // STAB - SELECTIVE TABULATION + // arbitrary choice + goto_htab((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1), 1); + break; + // case 0x205F: // GCC - GRAPHIC CHARACTER COMBINATION + // case 0x2060: // TATE - TABULATION ALIGNED TRAILING EDGE + // case 0x2061: // TALE - TABULATION ALIGNED LEADING EDGE + // case 0x2062: // TAC - TABULATION ALIGNED CENTRED + // case 0x2063: // TAC - TABULATION ALIGNED CENTRED + case 0x2064: // TSR - TABULATION STOP REMOVE + clear_htab_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + // case 0x2065: // SCO - SELECT CHARACTER ORIENTATION + // case 0x2066: // SRCS - SET REDUCED CHARACTER SEPARATION + case 0x2067: // SCS - SET CHARACTER SPACING + set_cwidth(HUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + break; + case 0x2068: // SLS - SET LINE SPACING + set_lheight(VUNIT(get_ctrl_parameter(CTRL_IND, 0, 0, 0))); + break; + case 0x2069: // SPH - SET PAGE HOME + set_tmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 1)-1); + break; + case 0x206A: // SPL - SET PAGE LIMIT + set_bmargin_ch((uint8_t)get_ctrl_parameter(CTRL_IND, 0, 0, 0)); + break; + // case 0x206B: // SCP - SELECT CHARACTER PATH + } + ind = 0; + } + else // invalid value + { + ind = 0; + hanled = 0; + } + break; + case 0x90: // 1B 50 DCS - DEVICE CONTROL STRING + case 0x98: // 1B 58 SOS - START OF STRING + case 0x9A: // 1B 5A SCI - SINGLE CHARACTER INTRODUCER + case 0x9D: // 1B 5D OSC - OPERATING SYSTEM COMMAND + case 0x9E: // 1B 5E PM - PRIVACY MESSAGE + case 0x9F: // 1B 5F APC - APPLICATION PROGRAM COMMAND + if (in == 0x9C) // 1B 5C ST - STRING TERMINATOR + { + /* control string would be handled here if implemented */ + ind = 0; + } + else if (ind < N_ESC_BUFFER-1) + ++ind; + break; + default: + // how did we get here? + ind = 0; + handled = 0; + } + } + } + else + { + ind = 0; + handled = 0; + } + } + prev = in; + return handled; +} + +uint32_t get_ctrl_parameter ( + uint8_t * buffer, + uint8_t * * pos, + uint8_t * ind, + uint8_t * subind, + uint8_t id, + uint8_t subid, + uint32_t def +) +{ + uint32_t val = 0; + uint8_t ch; + uint8_t return_now = 0; + uint8_t return_default = 1; + + // add_outcome_str("get_ctrl_parameter()\r\n"); + // add_outcome_str("buffer == "); + // add_outcome_hex((uint16_t)buffer, 4); + // add_outcome_str("\r\n"); + // add_outcome_str("*buffer == "); + // add_outcome_hex(*buffer, 2); + // if ((*buffer >= 20) && (*buffer <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(*buffer); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + // add_outcome_str("*pos == "); + // add_outcome_hex((uint16_t)(*pos), 4); + // add_outcome_str("\r\n"); + // add_outcome_str("**pos == "); + // add_outcome_hex(**pos, 2); + // if ((**pos >= 20) && (**pos <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(**pos); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + // add_outcome_str("*ind == "); + // add_outcome_dec(*ind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("*subind == "); + // add_outcome_dec(*ind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("id == "); + // add_outcome_dec(id, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("subid == "); + // add_outcome_dec(subid, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("def == "); + // add_outcome_dec(def, 1); + // add_outcome_str("\r\n"); + + // too far, move to start. + if ((id < *ind) || ((id == *ind) && (subid < *subind))) + { + *pos = buffer; + *ind = 0; + *subind = 0; + // add_outcome_str("// too far, move to start.\r\n"); + // add_outcome_str("*pos == "); + // add_outcome_hex((uint16_t)(*pos), 8); + // add_outcome_str("\r\n"); + // add_outcome_str("**pos == "); + // add_outcome_hex(**pos, 2); + // if ((**pos >= 20) && (**pos <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(**pos); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + // add_outcome_str("*ind == "); + // add_outcome_dec(*ind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("*subind == "); + // add_outcome_dec(*subind, 1); + // add_outcome_str("\r\n"); + } + + if (*pos == buffer) // at start + { + // add_outcome_str("// at start\r\n"); + if ((*buffer < 0x30) || (*buffer > 0x3B)) // not a parameter string + { + // add_outcome_str("// not a parameter string\r\n"); + // add_outcome_str("return "); + // add_outcome_dec(def, 1); + // add_outcome_str("\r\n"); + return def; + } + } + + while (1) + { + ch = **pos; + // add_outcome_str("ch == "); + // add_outcome_hex(ch, 2); + // if ((ch >= 20) && (ch <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(ch); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + switch (ch) + { + case 0x30: // digit + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + // add_outcome_str("// digit\r\n"); + if ((*ind == id) && (*subind == subid)) + { + return_default = 0; + val *= 10; + val += ch - 0x30; + // add_outcome_str("return_default = 0//\r\n"); + // add_outcome_str("val == "); + // add_outcome_dec(val, 1); + // add_outcome_str("\r\n"); + } + ++(*pos); + // add_outcome_str("*pos == "); + // add_outcome_hex((uint16_t)(*pos), 8); + // add_outcome_str("\r\n"); + // add_outcome_str("**pos == "); + // add_outcome_hex(**pos, 2); + // if ((**pos >= 20) && (**pos <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(**pos); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + break; + case 0x3A: // : substring separator + // add_outcome_str("// : substring separator\r\n"); + if ((*ind == id) && (*subind == subid)) + { + return_now = 1; + // add_outcome_str("return_now = 1//\r\n"); + } + ++(*subind); + ++(*pos); + // add_outcome_str("*subind == "); + // add_outcome_dec(*subind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("*pos == "); + // add_outcome_hex((uint16_t)(*pos), 8); + // add_outcome_str("\r\n"); + // add_outcome_str("**pos == "); + // add_outcome_hex(**pos, 2); + // if ((**pos >= 20) && (**pos <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(**pos); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + break; + case 0x3B: // ; string separator + // add_outcome_str("// ; string separator\r\n"); + if ((*ind == id) && (*subind == subid)) + { + return_now = 1; + // add_outcome_str("return_now = 1//\r\n"); + } + ++(*ind); + *subind = 0; + ++(*pos); + // add_outcome_str("*ind == "); + // add_outcome_dec(*ind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("*subind == "); + // add_outcome_dec(*subind, 1); + // add_outcome_str("\r\n"); + // add_outcome_str("*pos == "); + // add_outcome_hex((uint16_t)(*pos), 8); + // add_outcome_str("\r\n"); + // add_outcome_str("**pos == "); + // add_outcome_hex(**pos, 2); + // if ((**pos >= 20) && (**pos <= 0x7E)) + // { + // add_outcome_str(" /* "); + // add_outcome(**pos); + // add_outcome_str(" */ "); + // } + // add_outcome_str("\r\n"); + break; + default: // end of parameter strings + // add_outcome_str("// end of parameter strings\r\n"); + // add_outcome_str("return_now = 1//\r\n"); + return_now = 1; + } + + if (return_now) + { + // add_outcome_str("return "); + // add_outcome_dec(return_default ? def : val, 1); + // add_outcome_str("\r\n"); + return return_default ? def : val; + } + } +} + +uint8_t handle_menu (const uint8_t key) +{ + static uint8_t menu_active = 0; + static uint8_t function = MENU_NONE; + static uint8_t allow_output = 0; + static uint16_t value=0; + uint8_t x; + + if (!menu_active) + { + if (key == MENU_ENTER) + { + menu_active = 1; + function = MENU_NONE; + allow_output = 0; + set_alarm = 1; + } + } + else if (function == MENU_NONE) + { + function = key; + value = 0; + switch (key) + { + case MENU_ENTER: + case MENU_OUTPUT: + function = MENU_NONE; + allow_output = 1; + add_income_str(TEXT_MENU_LIST, 1); + set_alarm = 1; + break; + case MENU_EXIT: + case MENU_CONFIRM: + menu_active = 0; + if (allow_output) add_income_str(TEXT_MENU_EXIT, 1); + set_alarm = 3; + break; + case MENU_BAUD: + if (allow_output) add_income_str(TEXT_MENU_BAUD, 1); + break; + case MENU_BITS: + if (allow_output) add_income_str(TEXT_MENU_BITS, 1); + break; + case MENU_FLOW: + if (allow_output) add_income_str(TEXT_MENU_FLOW, 1); + break; + case MENU_ECHO: + if (allow_output) add_income_str(TEXT_MENU_ECHO, 1); + break; + case MENU_DELETE: + if (allow_output) add_income_str(TEXT_MENU_DELETE, 1); + break; + case MENU_NEWLINE: + if (allow_output) add_income_str(TEXT_MENU_NEWLINE, 1); + break; + case MENU_REPLACE: + if (allow_output) add_income_str(TEXT_MENU_REPLACE, 1); + break; + case MENU_ENCODING: + if (allow_output) add_income_str(TEXT_MENU_ENCODING, 1); + break; + case MENU_PWIDTH: + if (allow_output) add_income_str(TEXT_MENU_PWIDTH, 1); + break; + case MENU_LMARGIN: + if (allow_output) add_income_str(TEXT_MENU_LMARGIN, 1); + break; + case MENU_RMARGIN: + if (allow_output) add_income_str(TEXT_MENU_RMARGIN, 1); + break; + case MENU_TWIDTH: + if (allow_output) add_income_str(TEXT_MENU_TWIDTH, 1); + break; + case MENU_PHEIGHT: + if (allow_output) add_income_str(TEXT_MENU_PHEIGHT, 1); + break; + case MENU_TMARGIN: + if (allow_output) add_income_str(TEXT_MENU_TMARGIN, 1); + break; + case MENU_BMARGIN: + if (allow_output) add_income_str(TEXT_MENU_BMARGIN, 1); + break; + case MENU_THEIGHT: + if (allow_output) add_income_str(TEXT_MENU_THEIGHT, 1); + break; + case MENU_HTAB: + if (allow_output) add_income_str(TEXT_MENU_HTAB, 1); + break; + case MENU_VTAB: + if (allow_output) add_income_str(TEXT_MENU_VTAB, 1); + break; + case MENU_CWIDTH: + if (allow_output) add_income_str(TEXT_MENU_CWIDTH, 1); + break; + case MENU_LHEIGHT: + if (allow_output) add_income_str(TEXT_MENU_LHEIGHT, 1); + break; + case MENU_PAPER: + if (allow_output) add_income_str(TEXT_MENU_PAPER, 1); + break; + default: + function = MENU_NONE; + } + if (function != MENU_NONE) + set_alarm = 2; + } + else + { + switch(key) + { + case KEY_0: + case KEY_1: + case KEY_2: + case KEY_3: + case KEY_4: + case KEY_5: + case KEY_6: + case KEY_7: + case KEY_8: + case KEY_9: + x=KEYMAP_LIST[0][key]; + if(allow_output) + add_income(x, 1); + value *= 10; + value += x-'0'; + set_alarm = 1; + break; + case MENU_EXIT: + function = MENU_NONE; + if(allow_output) + add_income_str(TEXT_MENU_CANCEL, 1); + set_alarm = 2; + break; + case MENU_ENTER: + case MENU_OUTPUT: + function = MENU_NONE; + if(allow_output) + add_income_str(TEXT_MENU_LIST, 1); + set_alarm = 2; + case MENU_CONFIRM: + switch (function) + { + case MENU_BAUD: + switch (value) + { + case 1: + value = UART_BAUD_150; + break; + case 2: + value = UART_BAUD_300; + break; + case 3: + value = UART_BAUD_600; + break; + case 4: + value = UART_BAUD_1200; + break; + case 5: + value = UART_BAUD_2400; + break; + case 6: + value = UART_BAUD_4800; + break; + case 7: + value = UART_BAUD_9600; + break; + case 8: + value = UART_BAUD_19200; + break; + case 9: + value = UART_BAUD_38400; + break; + case 0: + value = UART_BAUD_115200; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_baudrate(value); + store_single_config(ID_BAUD); + value = 0; + } + break; + case MENU_BITS: + switch (value) + { + case 1: + value = UART_8N1; + break; + case 2: + value = UART_8E1; + break; + case 3: + value = UART_8O1; + break; + case 4: + value = UART_8N2; + break; + case 5: + value = UART_8E2; + break; + case 6: + value = UART_8O2; + break; + case 7: + value = UART_7N1; + break; + case 8: + value = UART_7E1; + break; + case 9: + value = UART_7O1; + break; + case 10: + value = UART_7N2; + break; + case 11: + value = UART_7E2; + break; + case 12: + value = UART_7O2; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_serial_mode(value); + store_single_config(ID_BITS); + value = 0; + } + break; + case MENU_FLOW: + switch (value) + { + case 1: + value = (flow & ~FLOW_HW) | FLOW_FD; + break; + case 2: + value = (flow & ~FLOW_HW) | FLOW_HD_DTE; + break; + case 3: + value = (flow & ~FLOW_HW) | FLOW_HD_DCE; + break; + case 4: + value = (flow & ~FLOW_HW) | FLOW_NONE; + break; + case 5: + value = (flow & ~FLOW_SW) | FLOW_XONOFF; + break; + case 6: + value = (flow & ~FLOW_SW) | FLOW_NONE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_flowcontrol(value); + store_single_config(ID_FLOW); + value = 0; + } + break; + case MENU_ECHO: + switch (value) + { + case 1: + mode |= MODE_ECHO; + break; + case 2: + mode &= ~MODE_ECHO; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_MODE); + value = 0; + } + break; + case MENU_NEWLINE: + switch (value) + { + case 1: + nl_mode = (nl_mode & ~NL_IMPLICIT_CR) | NL_IMPLICIT_LF; + break; + case 2: + nl_mode = (nl_mode & ~NL_IMPLICIT_LF) | NL_IMPLICIT_CR; + break; + case 3: + nl_mode |= NL_CATCH_ALL; + break; + case 4: + nl_mode &= ~NL_CATCH_ALL; + break; + case 5: + nl_mode = (nl_mode & ~NL_SEND_LF) | NL_SEND_CR; + break; + case 6: + nl_mode = (nl_mode & ~NL_SEND_CR) | NL_SEND_LF; + break; + case 7: + nl_mode |= NL_SEND_CRLF; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_MODE); + value = 0; + } + break; + case MENU_DELETE: + switch (value) + { + case 1: + bs_mode |= BS_BS; + break; + case 2: + bs_mode &= ~BS_BS; + break; + case 3: + bs_mode |= BS_DEL; + break; + case 4: + bs_mode &= ~BS_DEL; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_BS_MODE); + value = 0; + } + break; + case MENU_REPLACE: + switch (value) + { + case 1: + replace = REPLACE_SYMBOL; + break; + case 2: + replace = REPLACE_QUEST; + break; + case 3: + replace = REPLACE_UNDER; + break; + case 4: + replace = REPLACE_SPACE; + break; + case 5: + replace = REPLACE_IGNORE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + store_single_config(ID_REPLACE); + value = 0; + } + break; + case MENU_ENCODING: + switch (value) + { + case 1: + value = ENC_ISO8859_1; + break; + case 2: + value = ENC_ISO8859_2; + break; + // case 3: + // value = ENC_ISO8859_3; + // break; + // case 4: + // value = ENC_ISO8859_4; + // break; + // case 9: + // value = ENC_ISO8859_9; + // break; + // case 10: + // value = ENC_ISO8859_10; + // break; + // case 13: + // value = ENC_ISO8859_13; + // break; + // case 15: + // value = ENC_ISO8859_15; + // break; + // case 16: + // value = ENC_ISO8859_16; + // break; + case 1250: + value = ENC_CP1250; + break; + case 852: + value = ENC_CP852; + break; + case 8: + value = encoding | ENC_UNI; + break; + default: + value = 0xffff; + break; + } + if (value != 0xffff) + { + set_encoding(value); + store_single_config(ID_ENCODING); + value = 0; + } + break; + case MENU_PWIDTH: + if (value == 0) + value = 0xffff; + else + { + value *= cwidth_aim; + if (value > HPOS_LIMIT) + value = 0xffff; + else + { + set_lwidth(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + } + break; + case MENU_LMARGIN: + value *= cwidth_aim; + if (value > (HPOS_LIMIT - cwidth_aim)) + value = 0xffff; + else + { + set_lmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + break; + case MENU_RMARGIN: + value *= cwidth_aim; + if (value > (lwidth - cwidth_aim)) + value = 0xffff; + else + { + value = lwidth - value; + set_rmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + break; + case MENU_TWIDTH: + if (value == 0) + value = 0xffff; + else + { + value *= cwidth_aim; + value += lmargin_aim; + if (value > HPOS_LIMIT) + value = 0xffff; + else + { + set_rmargin(value); + store_single_config(ID_LWIDTH); + store_single_config(ID_LMARGIN); + store_single_config(ID_RMARGIN); + value = 0; + } + } + break; + case MENU_PHEIGHT: + if (value == 0) + value = 0xffff; + else + { + value *= lheight; + if (value > VPOS_LIMIT) + value = 0xffff; + else + { + set_pheight(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + } + break; + case MENU_TMARGIN: + value *= lheight; + if (value > (VPOS_LIMIT - lheight)) + value = 0xffff; + else + { + set_tmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + break; + case MENU_BMARGIN: + value *= lheight; + if (value > (pheight - lheight)) + value = 0xffff; + else + { + value = pheight - value; + set_bmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + break; + case MENU_THEIGHT: + if (value == 0) + value = 0xffff; + else + { + value *= lheight; + value += tmargin; + if (value > VPOS_LIMIT) + value = 0xffff; + else + { + set_bmargin(value); + store_single_config(ID_PHEIGHT); + store_single_config(ID_TMARGIN); + store_single_config(ID_BMARGIN); + value = 0; + } + } + break; + case MENU_HTAB: + if (value == 0) + value = 0xffff; + else + { + set_twidth_ch(value); + store_single_config(ID_HTAB); + value = 0; + } + break; + case MENU_VTAB: + if (value == 0) + value = 0xffff; + else + { + set_theight_ch(value); + store_single_config(ID_VTAB); + value = 0; + } + break; + case MENU_CWIDTH: + switch (value) + { + case 1: + value = WIDTH_15; + break; + case 2: + value = WIDTH_12; + break; + case 3: + value = WIDTH_10; + break; + case 4: + value = WIDTH_6; + break; + case 5: + value = WIDTH_4; + break; + case 6: + value = WIDTH_3; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_cwidth(value); + store_single_config(ID_CWIDTH); + value = 0; + } + break; + case MENU_LHEIGHT: + switch (value) + { + case 1: + value = HEIGHT_6; + break; + case 2: + value = HEIGHT_4; + break; + case 3: + value = HEIGHT_3; + break; + case 4: + value = HEIGHT_2; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + set_lheight(value); + store_single_config(ID_CWIDTH); + value = 0; + } + break; + case MENU_PAPER: + switch (value) + { + case 1: + value = PAPER_CONTINUOUS; + break; + case 2: + value = PAPER_SINGLE; + break; + default: + value = 0xffff; + } + if (value != 0xffff) + { + paper = value; + store_single_config(ID_PAPER); + value = 0; + } + break; + default: + value = 1; + } + function = MENU_NONE; + if (!value) + { + if(allow_output) + add_income_str(TEXT_MENU_OK, 1); + set_alarm = 2; + } + else + { + if(allow_output) + add_income_str(TEXT_MENU_FAIL, 1); + set_alarm = 5; + } + break; + } + } + + + + return menu_active; +} + diff --git a/uni.py b/uni.py new file mode 100755 index 0000000..6e2b239 --- /dev/null +++ b/uni.py @@ -0,0 +1,17 @@ +#!/usr/bin/python3 + +N = 0x0300 + +def single_line(n): + line = '%04X|' % n + if (n != 0x00) and (n != 0x80): + for i in range (n, min(N, n + 0x20)): + line += chr(i) + ' ' + print (line) + +print (' | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ') +print (' |0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F ') +print ('----+----------------------------------------------------------------') +for i in range (0x00, N, 0x20): + single_line(i) + diff --git a/uni.txt b/uni.txt new file mode 100644 index 0000000..903886f --- /dev/null +++ b/uni.txt @@ -0,0 +1,27 @@ + | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + |0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F +----+---------------------------------------------------------------- +0000| +0020| ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +0040|@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ +0060|` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  +0080| +00A0|  ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ +00C0|À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß +00E0|à á â ã ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ +0100|Ā ā Ă ă Ą ą Ć ć Ĉ ĉ Ċ ċ Č č Ď ď Đ đ Ē ē Ĕ ĕ Ė ė Ę ę Ě ě Ĝ ĝ Ğ ğ +0120|Ä  Ä¡ Ä¢ Ä£ Ĥ Ä¥ Ħ ħ Ĩ Ä© Ī Ä« Ĭ Ä­ Ä® į Ä° ı IJ ij Ä´ ĵ Ķ Ä· ĸ Ĺ ĺ Ä» ļ Ľ ľ Ä¿ +0140|ŀ Ł ł Ń ń Ņ ņ Ň ň ʼn Ŋ ŋ Ō ō Ŏ ŏ Ő ő Œ œ Ŕ ŕ Ŗ ŗ Ř ř Ś ś Ŝ ŝ Ş ş +0160|Å  Å¡ Å¢ Å£ Ť Å¥ Ŧ ŧ Ũ Å© Ū Å« Ŭ Å­ Å® ů Å° ű Ų ų Å´ ŵ Ŷ Å· Ÿ Ź ź Å» ż Ž ž Å¿ +0180|ƀ Ɓ Ƃ ƃ Ƅ ƅ Ɔ Ƈ ƈ Ɖ Ɗ Ƌ ƌ ƍ Ǝ Ə Ɛ Ƒ ƒ Ɠ Ɣ ƕ Ɩ Ɨ Ƙ ƙ ƚ ƛ Ɯ Ɲ ƞ Ɵ +01A0|Æ  Æ¡ Æ¢ Æ£ Ƥ Æ¥ Ʀ Ƨ ƨ Æ© ƪ Æ« Ƭ Æ­ Æ® Ư Æ° Ʊ Ʋ Ƴ Æ´ Ƶ ƶ Æ· Ƹ ƹ ƺ Æ» Ƽ ƽ ƾ Æ¿ +01C0|ǀ ǁ ǂ ǃ DŽ Dž dž LJ Lj lj NJ Nj nj Ǎ ǎ Ǐ ǐ Ǒ ǒ Ǔ ǔ Ǖ ǖ Ǘ ǘ Ǚ ǚ Ǜ ǜ ǝ Ǟ ǟ +01E0|Ç  Ç¡ Ç¢ Ç£ Ǥ Ç¥ Ǧ ǧ Ǩ Ç© Ǫ Ç« Ǭ Ç­ Ç® ǯ Ç° DZ Dz dz Ç´ ǵ Ƕ Ç· Ǹ ǹ Ǻ Ç» Ǽ ǽ Ǿ Ç¿ +0200|Ȁ ȁ Ȃ ȃ Ȅ ȅ Ȇ ȇ Ȉ ȉ Ȋ ȋ Ȍ ȍ Ȏ ȏ Ȑ ȑ Ȓ ȓ Ȕ ȕ Ȗ ȗ Ș ș Ț ț Ȝ ȝ Ȟ ȟ +0220|È  È¡ È¢ È£ Ȥ È¥ Ȧ ȧ Ȩ È© Ȫ È« Ȭ È­ È® ȯ È° ȱ Ȳ ȳ È´ ȵ ȶ È· ȸ ȹ Ⱥ È» ȼ Ƚ Ⱦ È¿ +0240|ɀ Ɂ ɂ Ƀ Ʉ Ʌ Ɇ ɇ Ɉ ɉ Ɋ ɋ Ɍ ɍ Ɏ ɏ ɐ ɑ ɒ ɓ ɔ ɕ ɖ ɗ ɘ ə ɚ ɛ ɜ ɝ ɞ ɟ +0260|É  É¡ É¢ É£ ɤ É¥ ɦ ɧ ɨ É© ɪ É« ɬ É­ É® ɯ É° ɱ ɲ ɳ É´ ɵ ɶ É· ɸ ɹ ɺ É» ɼ ɽ ɾ É¿ +0280|ʀ ʁ ʂ ʃ ʄ ʅ ʆ ʇ ʈ ʉ ʊ ʋ ʌ ʍ ʎ ʏ ʐ ʑ ʒ ʓ ʔ ʕ ʖ ʗ ʘ ʙ ʚ ʛ ʜ ʝ ʞ ʟ +02A0|Ê  Ê¡ Ê¢ Ê£ ʤ Ê¥ ʦ ʧ ʨ Ê© ʪ Ê« ʬ Ê­ Ê® ʯ Ê° ʱ ʲ ʳ Ê´ ʵ ʶ Ê· ʸ ʹ ʺ Ê» ʼ ʽ ʾ Ê¿ +02C0|ˀ ˁ ˂ ˃ ˄ ˅ ˆ ˇ ˈ ˉ ˊ ˋ ˌ ˍ ˎ ˏ ː ˑ ˒ ˓ ˔ ˕ ˖ ˗ ˘ ˙ ˚ ˛ ˜ ˝ ˞ ˟ +02E0|Ë  Ë¡ Ë¢ Ë£ ˤ Ë¥ ˦ ˧ ˨ Ë© ˪ Ë« ˬ Ë­ Ë® ˯ Ë° ˱ ˲ ˳ Ë´ ˵ ˶ Ë· ˸ ˹ ˺ Ë» ˼ ˽ ˾ Ë¿ diff --git a/update-template.py b/update-template.py new file mode 100755 index 0000000..803fce0 --- /dev/null +++ b/update-template.py @@ -0,0 +1,110 @@ +#!/usr/bin/python3 + +import sys +import re + +mode = '' +encodings = [] +sequences = {} +ch = 0 +sequence = [] +key = '' +keyvalue = -1 +keymap = {} + +l = len(sys.argv) +if l >= 2: + file_in = sys.argv[1] + if l >= 3: + file_out = sys.argv[2] + else: + file_out = file_in +else: + file_in='' + file_out='' + + +with (open(file_in, 'rt', encoding='utf-8') if file_in else sys.stdin) as file: + for line in file: + i = line.find('#') + if i >= 0: + line = line[0:i] + line = line.strip() + + m = re.search('^([A-Za-z0-9_]+):$', line) + if m: + if len(sequence) != 0: + sequences[ch] = sequence + sequence = [] + if keyvalue >= 0: + keymap[key] = keyvalue + keyvalue = -1 + t = m.group(1) + if t == 'encoding': + mode = 'encoding' + elif re.search('^[0-9A-Fa-f]+$', t): + mode = 'sequence' + ch = int(t, 16) + sequence = [] + elif re.search('^[0-9A-Z_]+$', t): + mode = 'key' + key = t + keyvalue = -1 + else: + mode = '' + elif line != '': + if mode == 'encoding': + encodings.append(line) + elif mode == 'sequence': + sequence.append(line) + elif mode == 'key': + if re.search('^([0-9A-Fa-f]){2,4}$', line): + keyvalue = int(line, 16) + elif len(line) == 1: + keyvalue = ord(line) + +if len(sequence) != 0: + sequences[ch] = sequence + sequence = [] + +if keyvalue >= 0: + keymap[key] = keyvalue + keyvalue = -1 + +char_list = list(range(0x20, 0x80)) +B = [bytes([i]) for i in range (0x80, 0x100)] + +for e in encodings: + for b in B: + t = b.decode(e, errors='ignore') + if t == '': + t = ' ' + c = ord(t) + if not (c in char_list): + char_list.append(c) + +for c in sequences: + if not (c in char_list): + char_list.append(c) +char_list = sorted(char_list) + +with (open(file_out, 'wt', encoding='utf-8') if file_out else sys.stdout) as file: + print('encoding:', file=file) + for e in encodings: + print('\t' + e, file=file) + + print('', file=file) + + for c in char_list: + print(('%04X:' % c) + ('' if (0x7f <= c <= 0x9f) else (" # '" + chr(c) + "'")), file=file) + if c in sequences: + for k in sequences[c]: + print('\t' + k, file=file) + + print('', file=file) + + for k in keymap: + print (k + ':', file=file) + c = keymap[k] + print (('\t%04X' % c) + ('' if ((0x7f <= c <= 0x9f) or (c < 0x20)) else (" # '" + chr(c) + "'")), file=file) + -- 2.30.2