61de403bc86b000cf7c6f7436f7dcd653cb18ae1
[uccvend-snackrom.git] / ROM2 / main.c
1 #include "display.h"
2 #include "keypad.h"
3 #include "chime.h"
4 #include "server.h"
5 #include "coinmech.h"
6 #include "vend.h"
7
8 u16 uid;
9 u16 pin;
10 u8 selection;
11
12 u16 scroll_timer;
13 u16 coin_value;
14
15 bool uid_enter() {
16         u8 uidpos;
17         /* the user has started to type in his/her UID. grab the last key and continue
18          * reading. Returns true if a UID was entered successfully.
19          * The UID will be entered as 5 digits. (shorter uids should be pre-padded
20          * with zeros)
21          */
22         uid = last_key%10; /* 10 => 0, it was _not_ reset (hopefuly :) */
23         set_msg("UID?      ", WRAP_NONE);
24         set_char((last_key%10)+'0', 5);
25
26         for (uidpos = 2; uidpos <= 5; uidpos++) {
27                 keypad_getkey();
28                 if (last_key == KEY_RESET) {
29                         uid = 0;
30                         return 0;
31                 }
32                 uid = (uid*10) + (last_key%10);
33                 set_char((last_key%10)+'0', 4+uidpos);
34         }
35         return (uid!=0);
36 }
37
38 bool pin_enter() {
39         u8 pinpos;
40         /* We ask for a pin, display a PIN: prompt. PINs must be a 4 digit number.
41          * Strictly, they must be 16-bit, but it's easier to use the guarantee that
42          * 4-digits numbers are < 65536
43          *
44          * Also display X's on screen as the pin is entered.
45          */
46         pin = 0;
47         set_msg("PIN?      ", WRAP_NONE);
48         for (pinpos = 1; pinpos <= 4; pinpos++) {
49                 keypad_getkey();
50                 if (last_key == KEY_RESET) {
51                         pin = 0;
52                         return 0;
53                 }
54                 pin = (pin*10) + (last_key%10);
55                 set_char('X', 4+pinpos);
56         }
57         return 1;
58 }
59
60 void make_request(u8 selection) {
61         set_msg("REQUESTING", WRAP_NONE); /* XXX: maybe this isn't needed? */
62         switch(server_request(uid, pin, selection)) {
63                 case REQUEST_OK:
64                         set_msg("THANK YOU!", WRAP_NONE);
65                         break;
66                 case REQUEST_NO_MONEY:
67                         set_msg("NO MONEY!", WRAP_NONE);
68                         break;
69                 case REQUEST_SERVFAIL:
70                         set_msg("SERV FAIL!", WRAP_NONE);
71                         break;
72                 case REQUEST_EMPTY:
73                         set_msg("NONE LEFT!", WRAP_NONE);
74                         break;
75                 case REQUEST_INVAL:
76                         set_msg(" BAD SELN ", WRAP_NONE);
77                         break;
78         }
79         delay(1000);
80 }
81
82 void selection_menu() {
83         /* we have a valid username & PIN number */
84         /* either ask for a 2-digit selection, or wait for coins to be entered */
85         /* get the username somehow? */
86         set_msg("ENTER SELECTION OR INSERT COINS  ", WRAP_SCROLL);
87         selection = 0;
88         while(1) {
89                 if (coin_value) { /* we have coins inserted */
90                         int prev_coin = 0;
91                         /* alternate between the price and a confirm message */
92                         while (coin_value) {
93                                 if (prev_coin != coin_value) {
94                                         print_amount(coin_value);
95                                         append_msg("0: CONFIRM", WRAP_ALTERNATE);
96                                         prev_coin = coin_value;
97                                 }
98                                 keypad_read();
99                                 if (keypad_pressed()) {
100                                         switch (last_key) {
101                                                 case KEY_RESET:
102                                                         scroll_msg("PRESS COIN REFUND");
103                                                         while (coin_value);
104                                                         break;
105                                                 case KEY_0:
106                                                         switch (server_credit_account(uid, pin, coin_value)) {
107                                                                 case CREDIT_OK:
108                                                                         coin_eat();
109                                                                         set_msg(" SUCCESS! ", WRAP_NONE);
110                                                                         delay(1000);
111                                                                         break;
112                                                                 case CREDIT_FAIL:
113                                                                         set_msg(" FAILED!  " "PRESS COIN" "  REFUND  ",
114                                                                                         WRAP_ALTERNATE);
115                                                                         while (coin_value);
116                                                                         break;
117                                                         }
118                                                         break;
119                                         }
120                                 }
121                         }
122                         /* coins were refunded */
123                 }
124
125                 if (selection) { /* half way through a selection */
126                         keypad_read();
127                         if (keypad_pressed()) {
128                                 switch (last_key) {
129                                         case KEY_RESET:
130                                                 selection = 0;
131                                                 break;
132                                         case 0:
133                                                 break;
134                                         default:
135                                                 selection = selection * 10 + (last_key%10);
136                                                 make_request(selection);
137                                                 selection = 0;
138                                 }
139                         }
140                 } else { /* else listen for the first key of a selection */
141                         keypad_read();
142                         if (keypad_pressed()) {
143                                 switch (last_key) {
144                                         case KEY_RESET:
145                                                 return;
146                                         case 0:
147                                                 break;
148                                         default:
149                                                 selection = last_key%10;
150                                 }
151                         }
152                 }
153         }
154 }
155
156 void load_default_msg() {
157         /* FIXME: want this message to be changeable from the server */
158         set_msg("UNIVERSITY COMPUTER CLUB *** INSERT COINS OR USER-ID *** ",
159                         WRAP_SCROLL);
160 }
161
162 void service_menu() {
163         while (door_open()) { /* don't quit until door is closed */
164
165         }
166 }
167
168 int main() {
169         /* do stuff */
170         set_msg("UNIVERSITY", WRAP_NONE);
171         delay(1000);
172         set_msg(" COMPUTER ", WRAP_NONE);
173         delay(1000);
174         set_msg("   CLUB   ", WRAP_NONE);
175         delay(1000);
176
177         load_default_msg();
178         while(1) {
179                 /* this needs to be a relatively tight loop to make sure we catch
180                  * keypresses at the main menu
181                  */
182                 keypad_read();
183                 if (keypad_pressed()) {
184                         if (last_key != KEY_RESET) {
185                                 if (uid_enter() && pin_enter()) {
186                                         /* authenticate them */
187                                         switch (server_authenticate(uid, pin)) {
188                                                 case AUTH_GOOD:
189                                                         selection_menu();
190                                                         break;
191                                                 case AUTH_BAD:
192                                                         set_msg(" BAD USER ", WRAP_NONE);
193                                                         delay(1000);
194                                                         break;
195                                                 case AUTH_NO_MONEY:
196                                                         set_msg(" NO MONEY ", WRAP_NONE);
197                                                         delay(1000);
198                                                         break;
199                                                 case AUTH_LOCKED:
200                                                         set_msg("YOUR ACCOUNT IS LOCKED", WRAP_SCROLL);
201                                                         delay(1000);
202                                                         break;
203                                         }
204                                 }
205                                 uid = 0;
206                                 pin = 0;
207                                 /* move on */
208                         }
209                         load_default_msg();
210                 }
211
212                 /* test door switch   */
213                 if (door_open()) {
214                         service_menu();
215                         load_default_msg();
216                 }
217
218                 /* check on coin mech */
219         }
220 }
221
222 void _start() {
223         /* Initialize Stuff.  Particularly some memory locations that can only be
224          * written in the first 64 clock cycles upon reset.
225          */
226         display_init();
227         set_bus_expanded();
228         /* enable RTI & set rate */
229         /* init coin mech */
230         main();
231 }
232
233 void rti() {
234         chime(); /* turn chime on or of as need be */
235
236         /* scroll the display if need be too */
237         if (scroll_timer == 0) {
238                 display_shift();
239                 scroll_timer = SCROLL_TIME;
240         }
241         scroll_timer--;
242 }

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