add credit, add 013 debug timer message on keypress
[uccvend-snackrom.git] / ROM2 / main_basic.c
1 /*
2  * main_basic.c - a simplified main procedure that relies upon a ersver to do
3  * anything smart. Just be a dumb interface to a display, keypad, coin mech
4  * and snacks.
5  */
6
7 #include "version.h"
8 #include "display_basic.h"
9 #include "keypad.h"
10 #include "chime.h"
11 #include "coinmech.h"
12 #include "motors.h"
13 #include "sci.h"
14 #include "vend.h"
15 #include "xmodem.h"
16 #include "mic.h"
17
18 u8 last_standalone;
19 u8 last_switch_input;
20 u8 last_misc_input;
21 u16 last_coin_value;
22 bool last_door_open;
23 char display_buf[11];
24 /* cur_motor[0] is 0 for nothing, or 1..10, or 0xff to say redraw.
25  * cur_motor[1] is 0..9 and only meaningful is cur_motor[0] != 0. */
26 u8 cur_motor[2];
27
28 bool check_standalone() {
29         if (is_standalone()) {
30                 send_string("011 In standalone mode. Function disabled." CRLF);
31                 return 1;
32         }
33         return 0;
34 }
35
36 bool check_badpoke() {
37         if (cant_poke()) {
38                 send_string("099 Can't poke without flipping DIP SW 3." CRLF);
39                 return 1;
40         }
41         return 0;
42 }
43
44 void unknown_command() {
45         send_string("012 Unknown command. Type HELP for help." CRLF);
46 }
47
48 void motor_reply(u8 code) {
49         /* returns a message of the form MXYY - X is return code, YY is motor */
50         switch (code) {
51                 case MOTOR_SUCCESS:
52                         send_string("100 Vend successful." CRLF);
53                         break;
54                 case MOTOR_NOSLOT:
55                         send_string("151 No motor there." CRLF);
56                         break;
57                 case MOTOR_CURRENT_FAIL:
58                         send_string("152 Over current." CRLF);
59                         break;
60                 case MOTOR_HOME_FAIL:
61                         send_string("153 Home sensors failing." CRLF);
62                         break;
63                 default:
64                         send_string("159 Unknown motor error." CRLF);
65         }
66 }
67
68 void dispense_something() {
69         /* process a message VXX in sci_rx_buf where XX is motor number */
70         u8 slot;
71
72         if (check_standalone()) return;
73         if (must_verify() && !mic_verify((void*)sci_rx_buf)) {
74                 send_string("019 Message verification failed." CRLF);
75                 return;
76         }
77
78         if (my_strncmp("ALL", (char*)sci_rx_buf+1, 3)) {
79                 char motor[3];
80                 motor[2] = '\0';
81                 send_string("102 Vend all motors starting." CRLF);
82                 for (motor[0] = '0'; motor[0] <= '9'; motor[0]++) {
83                         for (motor[1] = '0'; motor[1] <= '9'; motor[1]++) {
84                                 if (motor[1] == '5') continue; /* there is now row 5 */
85                                 send_string("101 Vending ");
86                                 send_string(motor);
87                                 send_string(CRLF);
88                                 motor_reply(dispense_motor((motor[0]-'0')*10+(motor[1]-'0')));
89                         }
90                 }
91                 send_string("102 Vend all motors complete." CRLF);
92                 return;
93         }
94
95         if ((sci_rx_buf[1] < '0') || (sci_rx_buf[1] > '9') ||
96                 (sci_rx_buf[2] < '0') || (sci_rx_buf[2] > '9')) {
97                 sci_rx_buf[1] = sci_rx_buf[2] = '0';
98                 motor_reply(MOTOR_NOSLOT);
99                 return;
100         }
101
102         slot = (sci_rx_buf[1] - '0') * 10;
103         slot += sci_rx_buf[2] - '0';
104
105         motor_reply(dispense_motor(slot));
106 }
107
108 void write_to_display() {
109         /* process a message in the form DXXXXXXXXXX to send to display */
110         u8 i;
111         char buf[11];
112
113         if (check_standalone()) return;
114
115         for (i = 0; i < 10; i++)
116                 if (sci_rx_buf[i+1])
117                         buf[i] = sci_rx_buf[i+1];
118                 else
119                         break;
120
121         for (; i < 10; i++) /* pad the rest out with spaces */
122                 buf[i] = ' ';
123         buf[i] = '\0';
124
125         set_msg(buf);
126         send_string("300 Written." CRLF);
127 }
128
129 void send_balance() {
130         sci_tx_buf[0] = 'C';
131         sci_tx_buf[1] = have_change?'0':'1';
132         sci_tx_buf[2] = (coin_value/10000)%10;
133         sci_tx_buf[3] = (coin_value/1000)%10;
134         sci_tx_buf[4] = (coin_value/100)%10;
135         sci_tx_buf[5] = (coin_value/10)%10;
136         sci_tx_buf[6] = coin_value%10;
137         sci_tx_buf[8] = 0;
138         send_buffer(1);
139 }
140
141 void give_change() {
142         u16 cost;
143
144         if ((sci_rx_buf[1] < '0') || (sci_rx_buf[1] > '9') ||
145                 (sci_rx_buf[2] < '0') || (sci_rx_buf[2] > '9') ||
146                 (sci_rx_buf[3] < '0') || (sci_rx_buf[3] > '9') ||
147                 (sci_rx_buf[4] < '0') || (sci_rx_buf[4] > '9') ||
148                 (sci_rx_buf[5] < '0') || (sci_rx_buf[5] > '9')) {
149                 //send_nack();
150         }
151         cost = sci_rx_buf[1] - '0';
152         cost *= 10; cost = sci_rx_buf[2] - '0';
153         cost *= 10; cost = sci_rx_buf[3] - '0';
154         cost *= 10; cost = sci_rx_buf[4] - '0';
155         cost *= 10; cost = sci_rx_buf[5] - '0';
156
157         coin_cost(cost);
158         //send_ack();
159
160
161 void send_keypress(u8 key) {
162         /* send a packet of the form KX with X being the key, or R for reset */
163         if (is_standalone()) return;
164
165         sci_tx_buf[0] = '2';
166         if (key == KEY_RESET) {
167                 sci_tx_buf[1] = '1';
168                 sci_tx_buf[2] = '1';
169         } else {
170                 sci_tx_buf[1] = '0';
171                 sci_tx_buf[2] = (key%10)+'0';
172         }
173         sci_tx_buf[3] = '\0';
174         send_buffer(0);
175         send_string(" key." CRLF);
176 }
177
178 void send_timer() {
179         /* send a packet of the form KX with X being the key, or R for reset */
180         unsigned int t=get_timer_counter();
181
182         send_string("013 ");
183         sci_tx_buf[0] = '0'+(t/10000)%10;
184         sci_tx_buf[1] = '0'+(t/1000)%10;
185         sci_tx_buf[2] = '0'+(t/100)%10;
186         sci_tx_buf[3] = '0'+(t/10)%10;
187         sci_tx_buf[4] = '0'+t%10;
188         sci_tx_buf[5] = 0;
189         send_buffer(1);
190 }
191
192 void send_door_msg(bool open) {
193         if (is_standalone()) return;
194         sci_tx_buf[0] = '4';
195         sci_tx_buf[1] = '0';
196         sci_tx_buf[2] = open?'1':'0';
197         send_buffer(0);
198         if (open)
199                 send_string(" door open." CRLF);
200         else
201                 send_string(" door closed." CRLF);
202 }
203
204 void do_chime() {
205         if (check_standalone()) return;
206         if (sci_rx_buf[1] == '\0')
207                 chime_start();
208         else if (sci_rx_buf[1] == 'S') { /* synchronous beep */
209                 if (sci_rx_buf[2] == '\0')
210                         chime_start();
211                 else if (sci_rx_buf[3] != '\0' && sci_rx_buf[4] == '\0')
212                         chime_for(hex2u8(sci_rx_buf[2], sci_rx_buf[3]));
213                 else {
214                         send_string("510 Unknown chime duration." CRLF);
215                         return;
216                 }
217                 while (chime_count); /* spin */
218                 send_string("500 Chimed." CRLF);
219                 return;
220         } else if (sci_rx_buf[2] != '\0' && sci_rx_buf[3] == '\0')
221                 chime_for(hex2u8(sci_rx_buf[1], sci_rx_buf[2]));
222         else {
223                 send_string("510 Unknown chime duration." CRLF);
224                 return;
225         }
226         send_string("500 Chime started." CRLF);
227         return;
228 }
229
230 void do_silence() {
231         if (check_standalone()) return;
232         if (sci_rx_buf[1] == '\0')
233                 unchime_start();
234         else if (sci_rx_buf[1] == 'S') { /* synchronous beep */
235                 if (sci_rx_buf[2] == '\0')
236                         unchime_start();
237                 else if (sci_rx_buf[3] != '\0' && sci_rx_buf[4] == '\0')
238                         unchime_for(hex2u8(sci_rx_buf[2], sci_rx_buf[3]));
239                 else {
240                         send_string("511 Unknown silence duration." CRLF);
241                         return;
242                 }
243                 while (unchime_count); /* spin */
244                 send_string("501 Silenced." CRLF);
245                 return;
246         } else if (sci_rx_buf[2] != '\0' && sci_rx_buf[3] == '\0')
247                 unchime_for(hex2u8(sci_rx_buf[1], sci_rx_buf[2]));
248         else {
249                 send_string("511 Unknown silence duration." CRLF);
250                 return;
251         }
252         send_string("501 Silence started." CRLF);
253         return;
254 }
255
256 void print_switches(u8 prompted) {
257         if (prompted)
258                 send_string("600 ");
259         else
260                 send_string("610 ");
261         send_string(u82hex(misc_input));
262         send_string(" ");
263         send_string(u82hex(switch_input));
264         send_string(CRLF);
265 }
266
267 void ping_pong() {
268         /* make sure it's really a ping */
269         if (!my_strncmp("ING", (char*)sci_rx_buf+1, 3)) {
270                 unknown_command();
271                 return;
272         }
273         /* respond with ack & pong */
274         send_string("000 PONG!" CRLF);
275 }
276
277 u16 hex2addr(char* addrptr) {
278         u16 v;
279         v = hex2u8(addrptr[0], addrptr[1]) << 8;
280         v |= hex2u8(addrptr[2], addrptr[3]);
281         return v;
282 }
283
284 void peek() {
285         if (!my_strncmp("EEK", (char*)sci_rx_buf+1, 3)) {
286                 unknown_command();
287                 return;
288         }
289         if (check_badpoke()) return;
290         if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
291                         ishex(sci_rx_buf[7]) && sci_rx_buf[8] == '\0') {
292                 u16 v = hex2addr((char*)(sci_rx_buf+4));
293                 v = *((u8*)v);
294                 send_string("090 ");
295                 send_string(u82hex(v));
296                 send_string(CRLF);
297                 return;
298         }
299         send_string("091 Invalid location given." CRLF);
300 }
301
302 void poke() {
303         if (!my_strncmp("OKE", (char*)sci_rx_buf+1, 3)) {
304                 unknown_command();
305                 return;
306         }
307         if (check_badpoke()) return;
308         if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
309                         ishex(sci_rx_buf[7]) && ishex(sci_rx_buf[8]) && ishex(sci_rx_buf[9])
310                         && sci_rx_buf[10] == '\0') {
311                 u16 v;
312                 v = hex2addr((char*)(sci_rx_buf+4));
313                 *(u8*)v = hex2u8(sci_rx_buf[8], sci_rx_buf[9]);
314                 send_string("080 Written." CRLF);
315                 return;
316         }
317         send_string("081 Invalid location or byte given." CRLF);
318 }
319
320 void jump() {
321         if (!my_strncmp("UMP", (char*)sci_rx_buf+1, 3)) {
322                 unknown_command();
323                 return;
324         }
325         if (check_badpoke()) return;
326         if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
327                         ishex(sci_rx_buf[7]) && sci_rx_buf[8] == '\0') {
328                 u16 v = hex2addr((char*)(sci_rx_buf+4));
329                 send_string("070 Jumping now." CRLF);
330                 asm volatile ("jsr %0" : : "m"(*(u16*)v) : "d");
331                 send_string("071 And back." CRLF);
332                 return;
333         }
334         send_string("079 Invalid location given." CRLF);
335 }
336
337 void do_set_password() {
338         u8 i;
339         bool good = 1;
340         if (check_badpoke()) return;
341         for (i=1; i < 17; i++) {
342                 if (sci_rx_buf[i] == '\0') {
343                         good = 0;
344                         break;
345                 }
346         }
347         if (good && sci_rx_buf[17] != '\0') good = 0;
348         if (!good) {
349                 send_string("061 Password must be exactly 16 characters." CRLF);
350                 return;
351         }
352
353         mic_set_secret((char*)(sci_rx_buf+1));
354         send_string("060 Password has been set." CRLF);
355 }
356
357 void send_prompt() {
358         if (must_verify()) {
359                 send_string(u82hex(mic_challenge >> 8));
360                 send_string(u82hex(mic_challenge & 0xff));
361         }
362         send_string(is_standalone()?"% ":"# ");
363 }
364
365 void about() {
366         if (!my_strncmp("BOUT", (char*)sci_rx_buf+1, 4)) {
367                 unknown_command();
368                 return;
369         }
370         send_string(
371                 CRLF
372                 " ROM2 (C) 2004 Bernard Blackham <[email protected]>" CRLF
373                 " Revision: " VERSION_STRING "  Built: " DATEBUILT_STRING CRLF "" CRLF CRLF
374                 "   This snack machine was brought to you by " CRLF
375                 "    Bernard Blackham" CRLF
376                 "    Harry McNally" CRLF
377                 "    Mark Tearle" CRLF
378                 "    Michal Gornisiewicz" CRLF
379                 "    Nick Bannon" CRLF
380                 "    and others." CRLF
381                 "" CRLF
382                 " Another UCC project in action.      http://www.ucc.asn.au/" CRLF
383         );
384 }
385
386 void set_echo() {
387         if (my_strncmp("CHO ON", (char*)sci_rx_buf+1, 6))
388                 sci_echo = 1;
389         else if (my_strncmp("CHO OFF", (char*)sci_rx_buf+1, 7))
390                 sci_echo = 0;
391         else
392                 unknown_command();
393 }
394
395 void moo() {
396         if (!my_strncmp("OO", (char*)sci_rx_buf+1, 2)) {
397                 unknown_command();
398                 return;
399         }
400         send_string(
401 "       ____________" CRLF
402 "       |__________|" CRLF
403 "      /           /\\" CRLF
404 "     /  U C C    /  \\" CRLF
405 "    /___________/___/|" CRLF
406 "    |          |     |" CRLF
407 "    |  ==\\ /== |     |" CRLF
408 "    |   O   O  | \\ \\ |" CRLF
409 "    |     <    |  \\ \\|" CRLF
410 "   /|          |   \\ \\" CRLF
411 "  / |  \\_____/ |   / /" CRLF
412 " / /|          |  / /|" CRLF
413 "/||\\|          | /||\\/" CRLF
414 "    -------------|   " CRLF
415 "        | |    | | " CRLF
416 "       <__/    \\__>" CRLF
417 "" CRLF
418 "  ... Where's the cheese?" CRLF
419         );
420 }
421
422 void identify() {
423         send_string(
424                 "086 ROM " VERSION_STRING " " DATEBUILT_STRING CRLF
425         );
426 }
427
428 void help() {
429         send_string(
430                 "Valid commands are:" CRLF
431                 " ABOUT         ROM information" CRLF
432                 " B[S][nn]      beep [synchronously] for a duration nn (optional)" CRLF
433                 " C[S][nn]      silence [synchronously] for a duration nn (optional)" CRLF
434                 " Dxxxxxxxxxx   show a message on the display" CRLF
435                 " ECHO {ON|OFF} turn echo on or off" CRLF
436                 " GETROM        download the ROM source code using xmodem" CRLF
437                 " H[...]        this help screen" CRLF
438                 " IDENTIFY      report ROM version" CRLF
439                 "*JUMPxxxx      jumps to a subroutine at location xxxx" CRLF
440                 "*PEEKxxxx      returns the value of the byte at location xxxx" CRLF
441                 "*POKExxxxyy    sets the value of location xxxx to yy" CRLF
442                 " PING          pongs" CRLF
443                 " S[...]        query all internal switch states" CRLF
444                 "+Vnn           vend an item" CRLF
445                 "+VALL          vend all items" CRLF
446                 "*Wxxxxxxxxxxxx set a new password for authenticated vends. xxx=16 chars" CRLF
447                 "               password will be converted to uppercase" CRLF
448                 "" CRLF
449                 "Very few functions are available when the machine is in standalone " CRLF
450                 "mode (DIP SW 1 is set)" CRLF
451                 "+ denotes that this item requires authentication if DIP SW 2 is set" CRLF
452                 "* denotes that DIP SW 3 must be set to use these" CRLF
453                 "Commands starting with # are ignored (comments)" CRLF
454         );
455 }
456
457 extern const char _rom_src_data[];
458 extern const u16 _rom_src_len;
459 void getrom() {
460         if (!my_strncmp("ETROM", (char*)sci_rx_buf+1, 5)) {
461                 unknown_command();
462                 return;
463         }
464         char s[4];
465         
466         u16 rom_addr;
467         rom_addr = (u16)(&_rom_src_data);
468
469         send_string("Writing to serial port (maybe). Size is 0x");
470         send_string(u82hex(_rom_src_len >> 8));
471         send_string(u82hex(_rom_src_len & 0xff));
472         send_string("@0x");
473         send_string(u82hex(rom_addr >> 8));
474         send_string(u82hex(rom_addr & 0xff));
475         send_string(" with signature ");
476         s[0] = _rom_src_data[0];
477         s[1] = _rom_src_data[1];
478         s[2] = _rom_src_data[2];
479         s[3] = '\0';
480         send_string(s);
481         send_string(CRLF " Type YES to download rom.tar.lz via XMODEM: ");
482         msg_clr();
483         while (!sci_have_packet); /* spin */
484         if (!my_strncmp("YES", (char*)sci_rx_buf, 3)) {
485                 send_string(CRLF "Transfer cancelled." CRLF);
486                 return;
487         }
488
489         sci_init();
490         sci_doing_xmodem = 1;
491         if (!xmodem_init_xfer()) {
492                 sci_doing_xmodem = 0;
493                 send_string("XMODEM init failed. Nobody's listening :(" CRLF);
494                 return;
495         }
496         char *p = (char*)_rom_src_data;
497         char *end = (char*)_rom_src_data+_rom_src_len;
498         bool aborted = 0;
499         while (1) {
500                 if (p + 128 > end) {
501                         /* send partial packet */
502                         if (!xmodem_send_packet((char*)p, end-p)) aborted = 1;
503                         break;
504                 } if ((u16)p == 0xb600) {
505                         /* we have an eeprom here. skip it. */
506                         p += 0x0200;
507                         continue;
508                 } else if (!xmodem_send_packet((char*)p, 128)) {
509                         aborted = 1;
510                         break;
511                 }
512                 p += 128;
513         }
514
515         xmodem_finish_xfer();
516         sci_doing_xmodem = 0;
517         if (aborted)
518                 send_string(CRLF "Transfer aborted." CRLF);
519         else
520                 send_string(CRLF "Transfer complete." CRLF);
521 }
522
523 void quit() {
524         if (my_strncmp("UIT", (char*)sci_rx_buf+1, 3))
525                 send_string("013 You can't quit you doofus." CRLF);
526         else
527                 unknown_command();
528 }
529
530 int main() {
531         u8 i;
532         for (i = 0; i < 11; i++)
533                 display_buf[i] = ' ';
534         display_buf[10] = '\0';
535
536         changer_output = 0x7f;
537         _io_ports[M6811_PORTA] = 0xc0; /* display on. talking to serial port */
538         _io_ports[M6811_DDRA] = 0xfc;
539         _io_ports[M6811_DDRD] = 0x3e;
540         _io_ports[M6811_SPCR] = M6811_MSTR | M6811_SPR1;
541         set_misc_output(0x00);
542
543         display_init();
544         set_msg(" HELLO    ");
545         delay(1000);
546
547         unlock(); /* enable interrupts */
548
549         set_msg("  CRUEL   ");
550
551         //coinmech_init();
552         sci_init();
553         keypad_init();
554         last_coin_value = 0;
555         last_door_open = 0;
556
557         delay(1000);
558
559         set_msg("   WORLD  ");
560         delay(1000);
561
562         chime_start();
563
564         send_string("5N4X0RZ R US" CRLF);
565
566         last_standalone = is_standalone();
567         if (last_standalone)
568                 cur_motor[0] = 0xff;
569         else
570                 cur_motor[0] = 0;
571         send_prompt();
572
573         last_switch_input = switch_input;
574         last_misc_input = misc_input;
575
576         while(1) {
577                 if (cur_motor[0] == 0xff) { /* signal to say redraw screen */
578                         set_msg("*5N4X0RZ* ");
579                         cur_motor[0] = 0;
580                 }
581
582                 if (door_open() != last_door_open) {
583                         last_door_open = door_open();
584                         send_door_msg(last_door_open);
585                         chime_start();
586                         if (is_standalone())
587                                 set_msg(last_door_open?"DOOR OPEN ":"DOOR CLOSE");
588                 }
589
590                 if (last_standalone != is_standalone()) {
591                         /* somebody flicked the standalone switch */
592                         msg_clr();
593                         send_string(CRLF);
594                         send_prompt();
595                         last_standalone = is_standalone();
596                 }
597
598                 if (last_misc_input != misc_input) {
599                         print_switches(0);
600                         last_misc_input = misc_input;
601                 }
602
603                 if (last_switch_input != switch_input) {
604                         print_switches(0);
605                         last_switch_input = switch_input;
606                 }
607
608                 if (sci_have_packet) {
609                         send_string(CRLF);
610                         switch (sci_rx_buf[0]) {
611                                 case '\0':
612                                 case '#':
613                                         send_string(CRLF);
614                                         break;
615                                 case 'A':
616                                         about();
617                                         break;
618                                 case 'B': 
619                                         do_chime();
620                                         break;
621                                 case 'C': 
622                                         do_silence();
623                                         break;
624                                 case 'D':
625                                         write_to_display();
626                                         break;
627                                 case 'E':
628                                         set_echo();
629                                         break;
630                                 case 'G':
631                                         getrom();
632                                         break;
633                                 case 'H':
634                                         help();
635                                         break;
636                                 case 'I':
637                                         identify();
638                                         break;
639                                 case 'M':
640                                         moo();
641                                         break;
642                                 case 'P':
643                                         if (sci_rx_buf[1] == 'I')
644                                                 ping_pong();
645                                         else if (sci_rx_buf[1] == 'O')
646                                                 poke();
647                                         else if (sci_rx_buf[1] == 'E')
648                                                 peek();
649                                         break;
650                                 case 'J':
651                                         jump();
652                                         break;
653                                 case 'Q':
654                                         quit();
655                                         break;
656                                 case 'S':
657                                         print_switches(1);
658                                         break;
659                                 case 'V':
660                                         dispense_something();
661                                         break;
662                                 case 'W':
663                                         do_set_password();
664                                         break;
665                                 default:
666                                         // shurg
667                                         unknown_command();
668                                         break;
669                         }
670                         msg_clr();
671                         send_prompt();
672                 }
673
674                 keypad_read();
675                 if (keypad_pressed()) {
676                         if (is_standalone()) {
677                                 if (last_key == KEY_RESET) {
678                                         cur_motor[0] = 0xff;
679                                 } else {
680                                         if (cur_motor[0]) {
681                                                 u8 motor_num;
682                                                 cur_motor[1] = last_key%10;
683                                                 display_buf[1] = cur_motor[1]+'0';
684                                                 set_msg(display_buf);
685
686                                                 motor_num = cur_motor[0]%10;
687                                                 motor_num *= 10;
688                                                 motor_num += cur_motor[1];
689                                                 switch (dispense_motor(motor_num)) {
690                                                         case MOTOR_HOME_FAIL:
691                                                                 set_msg(" HOME FAIL ");
692                                                                 break;
693                                                         case MOTOR_CURRENT_FAIL:
694                                                                 set_msg(" OVER CRNT ");
695                                                                 break;
696                                                         case MOTOR_SUCCESS:
697                                                                 set_msg("THANK  YOU");
698                                                                 break;
699                                                         case MOTOR_NOSLOT:
700                                                                 set_msg(" NO MOTOR ");
701                                                                 break;
702                                                         default:
703                                                                 set_msg("ERRRRRRRR?");
704                                                                 break;
705                                                 }
706
707                                                 display_buf[0] = ' ';
708                                                 display_buf[1] = ' ';
709                                                 cur_motor[0] = 0xff;
710                                                 delay(500);
711                                         } else {
712                                                 cur_motor[0] = last_key;
713                                                 display_buf[0] = (last_key%10)+'0';
714                                                 set_msg(display_buf);
715                                         }
716                                 }
717                         } else
718                                 send_keypress(last_key);
719                                 send_timer();
720                 }
721
722                 /*
723                 if (coin_value != last_coin_value) {
724                         send_balance();
725                         last_coin_value = coin_value;
726                 }
727                 */
728         }
729 }

UCC git Repository :: git.ucc.asn.au