Terminal program for MailStation devices
1#!/usr/bin/env ruby
2#
3# generate_scancodes
4# generate scancode lookup tables
5# msTERM
6#
7# Copyright (c) 2019 joshua stein <jcs@jcs.org>
8#
9# Permission to use, copy, modify, and distribute this software for any
10# purpose with or without fee is hereby granted, provided that the above
11# copyright notice and this permission notice appear in all copies.
12#
13# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20#
21
22META_KEY_BEGIN = 200
23
24KEYS = [
25 :MAIN_MENU,
26 :BACK,
27 :PRINT,
28 :F1,
29 :F2,
30 :F3,
31 :F4,
32 :F5,
33 :POWER,
34 :SIZE,
35 :SPELLING,
36 :EMAIL,
37 :PAGE_UP,
38 :PAGE_DOWN,
39 :CAPS_LOCK,
40 :LEFT_SHIFT,
41 :RIGHT_SHIFT,
42 :FN,
43 :UP,
44 :DOWN,
45 :LEFT,
46 :RIGHT,
47]
48
49META_KEY_NONE = 255
50
51UPPERCASES = {
52 "`" => "~",
53 "1" => "!",
54 "2" => "@",
55 "3" => "#",
56 "4" => "$",
57 "5" => "%",
58 "6" => "^",
59 "7" => "&",
60 "8" => "*",
61 "9" => "(",
62 "0" => ")",
63 "-" => "_",
64 "=" => "+",
65 "\\" => "|",
66 "[" => "{",
67 "]" => "}",
68 ";" => ":",
69 "'" => "\"",
70 "," => "<",
71 "." => ">",
72 "/" => "?",
73}
74
75CONTROLS = {
76 "a" => 1,
77 "b" => 2,
78 "c" => 3,
79 "d" => 4,
80 "e" => 5,
81 "f" => 6,
82 "g" => 7,
83 "h" => 8,
84 "i" => 9,
85 "j" => 10,
86 "k" => 11,
87 "l" => 12,
88 "m" => 13,
89 "n" => 14,
90 "o" => 15,
91 "p" => 16,
92 "q" => 17,
93 "r" => 18,
94 "s" => 19,
95 "t" => 20,
96 "u" => 21,
97 "v" => 22,
98 "w" => 23,
99 "x" => 24,
100 "y" => 25,
101 "z" => 26,
102 "3" => 27,
103 "[" => 27,
104 "4" => 28,
105 "\\" => 28,
106 "5" => 29,
107 "]" => 29,
108 "6" => 30,
109 "7" => 31,
110 "-" => 31,
111 "/" => 31,
112 "8" => 127,
113}
114
115SCANCODES = {
116 0 => :MAIN_MENU,
117 1 => :BACK,
118 2 => :PRINT,
119 3 => :F1,
120 4 => :F2,
121 5 => :F3,
122 6 => :F4,
123 7 => :F5,
124 15 => :POWER,
125 19 => "@",
126 20 => :SIZE,
127 21 => :SPELLING,
128 22 => :EMAIL,
129 23 => :PAGE_UP,
130 32 => "`",
131 33 => "1",
132 34 => "2",
133 35 => "3",
134 36 => "4",
135 37 => "5",
136 38 => "6",
137 39 => "7",
138 48 => "8",
139 49 => "9",
140 50 => "0",
141 51 => "-",
142 52 => "=",
143 53 => "\b", # backspace
144 54 => "\\",
145 55 => :PAGE_DOWN,
146 64 => "\t",
147 65 => "q",
148 66 => "w",
149 67 => "e",
150 68 => "r",
151 69 => "t",
152 70 => "y",
153 71 => "u",
154 80 => "i",
155 81 => "o",
156 82 => "p",
157 83 => "[",
158 84 => "]",
159 85 => ";",
160 86 => "'",
161 87 => "\n",
162 96 => :CAPS_LOCK,
163 97 => "a",
164 98 => "s",
165 99 => "d",
166 100 => "f",
167 101 => "g",
168 102 => "h",
169 103 => "j",
170 112 => "k",
171 113 => "l",
172 114 => ",",
173 115 => ".",
174 116 => "/",
175 117 => :UP,
176 118 => :DOWN,
177 119 => :RIGHT,
178 128 => :LEFT_SHIFT,
179 129 => "z",
180 130 => "x",
181 131 => "c",
182 132 => "v",
183 133 => "b",
184 134 => "n",
185 135 => "m",
186 144 => :FN,
187 147 => " ",
188 150 => :RIGHT_SHIFT,
189 151 => :LEFT,
190}
191
192File.open("#{__dir__}/../scancodes.inc", "w+") do |scf|
193 scf.puts "; AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb"
194 scf.puts "\t.equ\tMETA_KEY_BEGIN,\t#0d#{sprintf("%03d", META_KEY_BEGIN)}"
195 scf.puts "\t.equ\tMETA_KEY_NONE,\t#0d#{sprintf("%03d", META_KEY_NONE)}"
196 scf.puts
197
198 3.times do |x|
199 if x == 0
200 scf.puts "scancode_table:"
201 elsif x == 1
202 scf.puts
203 scf.puts "scancode_table_uppercase:"
204 elsif x == 2
205 scf.puts
206 scf.puts "scancode_table_control:"
207 end
208
209 (0 .. SCANCODES.keys.last).each do |sc|
210 if k = SCANCODES[sc]
211 origk = k
212 if k.is_a?(Symbol)
213 k = META_KEY_BEGIN + KEYS.index(k)
214 elsif k.is_a?(String)
215 k = k.ord
216 end
217 raise if !k
218
219 if x == 1
220 if u = UPPERCASES[origk]
221 k = u.ord
222 origk = u
223 elsif ("a" .. "z").include?(origk)
224 k = origk.upcase.ord
225 origk = origk.upcase
226 end
227 elsif x == 2
228 if u = CONTROLS[origk]
229 k = u
230 origk = u
231 end
232 end
233
234 scf.puts "\t.db #0d#{sprintf("%03d", k)}\t\t; #{origk.inspect}"
235 else
236 scf.puts "\t.db #0d#{sprintf("%03d", META_KEY_NONE)}"
237 end
238 end
239 end
240end
241
242File.open("#{__dir__}/../meta_keys.h", "w+") do |mkh|
243 mkh.puts "/* AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb */"
244 mkh.puts "#define\tMETA_KEY_BEGIN\t#{META_KEY_BEGIN}"
245
246 KEYS.each_with_index do |k,x|
247 mkh.puts "#define\tKEY_#{k}\t#{k.length < 3 ? "\t" : ""}#{META_KEY_BEGIN + x}"
248 end
249
250 mkh.puts
251 mkh.puts "#define\tMETA_KEY_NONE\t#{META_KEY_NONE}"
252end