4 * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2,
9 * or (at your option) any later version.
10 * This library / program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this library; see the file COPYING. If not, write to the
17 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 * As a special exception, if you link this(includeed from sdcc) library
21 * with other files, some of which are compiled with SDCC,
22 * to produce an executable, this library does not by itself cause
23 * the resulting executable to be covered by the GNU General Public License.
24 * This exception does not however invalidate any other reasons why
25 * the executable file might be covered by the GNU General Public License.
33 const char charcodemap[] = {charcode_0,
54 extern unsigned char pollkeybuf[32];
56 keyin_defs keyin_old[2];
69 for(i = 0; i < 2; i++) {
70 keyin_old[0].byte[i] = 0x00;
71 keyin_old[1].byte[i] = 0x00;
72 keyin_now.byte[i] = 0x00;
74 for(i = 0; i < 32; i++) keyin_fifo[i] = 0x00;
81 * Push to keyin fifo; not used atomic-writing.
84 void push_keyinfifo(char b) __critical
86 void push_keyinfifo(char b)
89 if(keyin_counter >= 31) {
91 keyin_readp++; // Discard data
93 if((keyin_readp > 31) || (keyin_readp < 0)) keyin_readp = 0;
95 keyin_fifo[keyin_nowp] = b;
98 if((keyin_nowp > 31) || (keyin_nowp < 0))keyin_nowp = 0;
102 * Pop from keyin fifo; not used atomic-reading.
105 char pop_keyinfifo(void) __critical
107 char pop_keyinfifo(void)
111 if(keyin_counter <= 0) {
113 return charcode_null ;
115 c = keyin_fifo[keyin_readp];
118 if((keyin_readp > 31) || (keyin_readp < 0)) keyin_readp = 0;
122 void printstr(char *s)
126 if(s == NULL) return;
128 if(s[p] == '\0') break;
134 void print_numeric_nosupress(unsigned int data, unsigned char digit)
140 if(digit == 0) return;
141 if(digit >= 5) digit = 5;
175 unsigned int subst_numeric(unsigned int start, unsigned char pos, unsigned int c)
180 unsigned char bcd[5];
183 if((pos == 4) && (c > 6)) return start;
187 for(i = 4; i >= 0; i--){
195 for(i = 3; i >= 0; i--){
199 if((bcd[4] == 6) && (val > 5535)) return val;
200 val = val + bcd[4] * 10000;
204 unsigned int read_numeric(unsigned int initial, unsigned char digit,
205 char startx, char starty)
217 _LOCATE(startx, starty);
218 print_numeric_nosupress(val, digit);
221 n = pollkeys(pollkeybuf, 60, 0);
226 val = subst_numeric(val, i, 0);
228 } else if((c >= charcode_1) && (c <= charcode_9)) {
229 val = subst_numeric(val, i, c - charcode_1 + 1);
231 } else if(c == charcode_f) {
234 } else if(c == charcode_a) {
238 } else if(c == charcode_b) {
243 } else if(c == charcode_e) {
245 } else if(c == charcode_d) {
254 unsigned char readkey_compare(void)
264 for(d = 0; d < 2; d++) {
266 for(b = 0; b < 8; b++){
268 if((keyin_now.byte[d] & shift) != 0) c++;
269 if((keyin_old[0].byte[d] & shift) != 0) c++;
270 if((keyin_old[1].byte[d] & shift) != 0) c++;
273 * Clear older-inputs on .
276 keyin_old[0].byte[d] &= ~shift;
277 keyin_old[1].byte[d] &= ~shift;
278 keyin_now.byte[d] &= ~shift;
279 push_keyinfifo(charcodemap[e]);
289 unsigned char readkey(void)
292 for(i = 0; i < 9; i++) {
293 idle_time_ms(2); // 2ms
297 return pop_keyinfifo();
305 * if((limit * 19.6ms) elapsed), break;
307 unsigned char pollkeys(unsigned char *p, unsigned int limit, unsigned char repeat)
309 unsigned int count = 0;
310 unsigned int lifetime = 0;
311 unsigned int penalty = 0;
315 idle_time_ms(10); // 0.78*20 = 15.6ms.
318 if(c != charcode_null) {
322 if(c == charcode_null) {
333 if((limit > 3) && (penalty > limit / 4)){
335 cold = charcode_null;
338 if(limit != 0) lifetime++;
339 if(lifetime > limit) break;
341 if(repeat != 0) cold = charcode_null;
345 unsigned char pollkey_single(void)
347 unsigned int count = 0;
348 unsigned int lifetime = 0;
349 unsigned int penalty = 0;
353 idle_time_ms(10); // 0.125 * 4 * 20 = 10ms.
354 c = readkey(); // 2 * 9 = 16ms
356 if(c != charcode_null) {
363 if(penalty > 20) cold = charcode_null;
369 * Initialize sequence:
374 * In interrupt/unsleep hook(call per Nms):
378 * In application handler:
379 * c = pop_keyinfifo();