1 /* pro_menu.c: Menu subsystem
2
3 Copyright (c) 1997-2003, Tarik Isani (xhomer@isani.org)
4
5 This file is part of Xhomer.
6
7 Xhomer is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10
11 Xhomer is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Xhomer; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21
22 /* TBD:
23 */
24
25 #ifdef PRO
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <dirent.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include "pdp11_defs.h"
33 #include "pro_lk201.h"
34
35 #define MENU_X 24 /* x position of top of menu */
36 #define MENU_Y 2 /* y position of top of menu */
37
38 #define MENU_BW 4 /* width of menu border */
39 #define MENU_AW 30 /* active width of menu */
40 #define MENU_W 2*MENU_BW+MENU_AW /* width of menu */
41
42 #define MENU_BH 2 /* height of menu border */
43 #define MENU_AH MENU_TOP_NUM /* active height of menu */
44 #define MENU_H 2*MENU_BH+2+MENU_AH /* height of menu */
45
46 #define MENU_PX (MENU_X+1)
47 #define MENU_PY (MENU_Y+MENU_BH+2+pro_menu_pos)
48
49 #define MENU_TOP_NUM 13 /* number of top level menu items */
50 #define MENU_SERIAL_NUM 8 /* number of serial menu items */
51 #define MENU_ABOUT_NUM 13 /* number of about menu items */
52
53 #define MENU_TOP 0
54 #define MENU_SERIAL 1
55 #define MENU_FILE 2
56 #define MENU_ABOUT 3
57
58 #define MENU_TOP_RETURN 0
59 #define MENU_TOP_SCREEN 1
60 #define MENU_TOP_RX0 2
61 #define MENU_TOP_RX1 3
62 #define MENU_TOP_RD0 4
63 #define MENU_TOP_COM 5
64 #define MENU_TOP_PTR 6
65 #define MENU_TOP_KB 7
66 #define MENU_TOP_SAVE 8
67 #define MENU_TOP_REST 9
68 #define MENU_TOP_RESET 10
69 #define MENU_TOP_ABOUT 11
70 #define MENU_TOP_SHUT 12
71
72 #define MENU_MAXENTRIES 1024 /* maximum number of menu entries */
73 #define MENU_MAXFILELEN 255 /* maximum filename length */
74
75 LOCAL int pro_menu_last_char; /* tracks last char, for auto-repeat */
76 LOCAL int pro_menu_key_ctrl; /* tracks whether ctrl key is depressed */
77 LOCAL int pro_menu_on; /* tracks whether menu is on */
78 LOCAL int pro_menu_top_start; /* start item number of item list */
79 LOCAL int pro_menu_top_pos; /* menu item selected */
80 LOCAL int pro_menu_serial_start; /* start item number of item list */
81 LOCAL int pro_menu_serial_pos; /* position of serial menu bar */
82 LOCAL int pro_menu_file_start; /* start item number of item list */
83 LOCAL int pro_menu_file_pos; /* position of file menu bar */
84 LOCAL int pro_menu_active; /* currently active menu */
85
86 LOCAL int pro_menu_start; /* start postion */
87 LOCAL int pro_menu_pos; /* current position */
88 LOCAL int pro_menu_items; /* number of menu items */
89
90 LOCAL char title[MENU_AW+1];
91 LOCAL char blank[MENU_W+1];
92 LOCAL char blank_top[MENU_W+1];
93 LOCAL char blank_bot[MENU_W+1];
94 LOCAL char item[MENU_MAXENTRIES][MENU_MAXFILELEN+1];
95 LOCAL int item_ok[MENU_MAXENTRIES];
96 LOCAL char menu_bar[MENU_W+1];
97
98
99 /* Place menu bar on menu */
100
pro_menu_bar(int pro_menu_pos)101 void pro_menu_bar (int pro_menu_pos)
102 {
103 pro_overlay_print(MENU_PX, MENU_PY, 1, 1, menu_bar);
104 }
105
106
107 /* Concatenate s2 and s3 into s1, limited by length n */
108
pro_menu_concat(char * s1,char * s2,char * s3,int n)109 void pro_menu_concat (char *s1, char *s2, char *s3, int n)
110 {
111 int i, pos;
112
113
114 pos = 0;
115
116 if (s2 != NULL)
117 for(i=0; i<strlen(s2); i++)
118 if (pos<n)
119 s1[pos++] = s2[i];
120
121 if (s3 != NULL)
122 for(i=0; i<strlen(s3); i++)
123 if (pos<n)
124 s1[pos++] = s3[i];
125
126 s1[pos] = '\0';
127 }
128
129
130 /* Make serial assignments */
131
pro_menu_assign_serial(int devnum,struct sercall ** dev,int * port)132 void pro_menu_assign_serial (int devnum, struct sercall **dev, int *port)
133 {
134 switch(devnum)
135 {
136 case 0:
137 case 1:
138 case 2:
139 case 3:
140 *dev = &pro_serial;
141 *port = devnum;
142 break;
143
144 case 4:
145 *dev = &pro_digipad;
146 *port = 0;
147 break;
148
149 case 5:
150 *dev = &pro_lk201;
151 *port = 0;
152 break;
153
154 case 6:
155 *dev = &pro_la50;
156 *port = 0;
157 break;
158
159 case 7:
160 *dev = &pro_null;
161 *port = 0;
162 break;
163
164 default:
165 break;
166 }
167 }
168
169
170 /* Return s2 + serial assignment printout in s1 */
171 /* Also return menu item number */
172
pro_menu_print_serial(char * s1,char * s2,struct sercall * dev,int port)173 int pro_menu_print_serial (char *s1, char *s2, struct sercall *dev, int port)
174 {
175 int item;
176 char s3[MENU_AW+1], s4[MENU_AW+1];
177
178
179 item = 0;
180
181 if (dev == &pro_serial)
182 {
183 sprintf(s4, "serial%d (", port);
184 pro_menu_concat(s3, s4, pro_serial_devname[port], MENU_AW);
185 pro_menu_concat(s4, s3, ")", MENU_AW);
186 item = port;
187 }
188 else if (dev == &pro_digipad)
189 {
190 sprintf(s4, "digipad");
191 item = 4;
192 }
193 else if (dev == &pro_lk201)
194 {
195 sprintf(s4, "lk201");
196 item = 5;
197 }
198 else if (dev == &pro_la50)
199 {
200 sprintf(s4, "la50");
201 item = 6;
202 }
203 else if (dev == &pro_null)
204 {
205 sprintf(s4, "null");
206 item = 7;
207 }
208
209 pro_menu_concat(s1, s2, s4, MENU_AW);
210
211 return item;
212 }
213
214
215 /* Update directory path name */
216
pro_menu_newdir(char ** dir,char * new)217 void pro_menu_newdir(char **dir, char *new)
218 {
219 int i, len;
220 char *temp;
221
222
223 /* Do nothing if current directory is specified */
224
225 if (strcmp(new, ".") != 0)
226 {
227 temp = strdup(*dir);
228
229 if (*dir != NULL)
230 free(*dir);
231
232 if (strcmp(new, "..") == 0)
233 {
234 /* Up one level */
235
236 /* Get last directory name
237 Remove it if it is not . or ..
238 Otherwise, add on a .. */
239
240 len = strlen(temp);
241
242 for(i=len-1; i>0; i--)
243 {
244 if (temp[i-1] == '/')
245 break;
246 }
247
248 if ((strcmp(temp+i, "./") == 0) || (strcmp(temp+i, "../") == 0))
249 {
250 *dir = malloc(len + 4);
251 strcpy(*dir, temp);
252 strcat(*dir, "../");
253 }
254 else
255 {
256 temp[i] = '\0';
257 *dir = strdup(temp);
258 }
259 }
260 else
261 {
262 /* Down one level */
263
264 len = strlen(temp) + strlen(new) + 2;
265 *dir = malloc(len);
266 strcpy(*dir, temp);
267 strcat(*dir, new);
268 strcat(*dir, "/");
269 }
270
271 free(temp);
272 }
273 }
274
275
276 /* Print menu */
277
pro_menu_print(int start)278 void pro_menu_print (int start)
279 {
280 int i;
281 char itmp[MENU_AW+1];
282
283
284 blank_top[0] = 24;
285 blank_top[MENU_W-1] = 26;
286
287 blank[0] = 31;
288 blank[MENU_W-1] = 27;
289
290 blank_bot[0] = 30;
291 blank_bot[MENU_W-1] = 28;
292
293 for(i=1; i<MENU_W-1; i++)
294 {
295 blank_top[i] = 25;
296 blank[i] = 32;
297 blank_bot[i] = 29;
298 }
299
300 blank_top[MENU_W] = '\0';
301 blank[MENU_W] = '\0';
302 blank_bot[MENU_W] = '\0';
303
304 pro_overlay_print(MENU_X, MENU_Y, 0, 1, blank_top);
305
306 for(i=1; i<MENU_H-1; i++)
307 pro_overlay_print(MENU_X, MENU_Y+i, 0, 1, blank);
308
309 pro_overlay_print(MENU_X, MENU_Y+MENU_H-1, 0, 1, blank_bot);
310
311 pro_overlay_print(MENU_X+MENU_BW, MENU_Y+MENU_BH, 0, 1, title);
312
313 for(i=0; i<MENU_AH; i++)
314 if ((i+start)<pro_menu_items)
315 {
316 pro_menu_concat(itmp, "", item[i+start], MENU_AW);
317 pro_overlay_print(MENU_X+MENU_BW, MENU_Y+MENU_BH+2+i, 0, item_ok[i+start], itmp);
318 }
319 }
320
321
322 /* Initialize and print file menu */
323
pro_menu_file(char ** filename)324 void pro_menu_file (char **filename)
325 {
326 DIR *dp;
327 struct dirent *ep;
328 struct stat statbuf;
329 int i, j;
330 char fname[MENU_MAXFILELEN+1];
331 char sname[MENU_MAXFILELEN+1];
332 char strtemp[MENU_MAXFILELEN+1];
333 char *dir = NULL;
334
335
336 pro_menu_active = MENU_FILE;
337 pro_menu_items = 1;
338 pro_menu_file_pos = 0;
339
340 if (filename == &pro_rx_file[0])
341 {
342 sprintf(strtemp, "Floppy 0 : ");
343 dir = pro_rx_dir[0];
344 }
345 else if (filename == &pro_rx_file[1])
346 {
347 sprintf(strtemp, "Floppy 1 : ");
348 dir = pro_rx_dir[1];
349 }
350 else if (filename == &pro_rd_file)
351 {
352 sprintf(strtemp, "Hard disk 0 : ");
353 dir = pro_rd_dir;
354 }
355
356 sprintf(item[0], " ");
357
358 pro_menu_concat(title, strtemp, dir, MENU_AW);
359
360 dp = opendir(dir);
361 if (dp != NULL)
362 {
363 do
364 {
365 ep = readdir(dp);
366
367 if (ep != NULL)
368 {
369 pro_menu_concat(fname, "", ep->d_name, MENU_MAXFILELEN);
370 pro_menu_concat(sname, dir, ep->d_name, MENU_MAXFILELEN);
371 stat(sname, &statbuf);
372
373 /* Check if link or regular file or directory */
374
375 if ((statbuf.st_mode&S_IFMT) == S_IFDIR)
376 {
377 pro_menu_concat(item[pro_menu_items], "1 ", fname, MENU_MAXFILELEN);
378 item_ok[pro_menu_items] = 1;
379 pro_menu_items++;
380 }
381 else if ((statbuf.st_mode&S_IFMT) == S_IFLNK)
382 {
383 pro_menu_concat(item[pro_menu_items], "2 ", fname, MENU_MAXFILELEN);
384 item_ok[pro_menu_items] = 1;
385 pro_menu_items++;
386 }
387 else if ((statbuf.st_mode&S_IFMT) == S_IFREG)
388 {
389 pro_menu_concat(item[pro_menu_items], "3 ", fname, MENU_MAXFILELEN);
390 item_ok[pro_menu_items] = 1;
391 pro_menu_items++;
392 }
393 }
394 }
395 while ((ep != NULL) && (pro_menu_items < (MENU_MAXENTRIES-1)));
396
397 (void) closedir(dp);
398
399 /* Sort directory */
400
401 for(j=pro_menu_items-1; j>1; j--)
402 for(i=pro_menu_items-1; i>1; i--)
403 {
404 if (strcmp(item[i], item[i-1]) < 0)
405 {
406 /* swap */
407
408 strcpy(strtemp, item[i-1]);
409 strcpy(item[i-1], item[i]);
410 strcpy(item[i], strtemp);
411 }
412 }
413
414 /* Replace first character and search for current name */
415
416 for(i=0; i<pro_menu_items; i++)
417 {
418 if (strcmp(*filename, item[i]+2) == 0)
419 pro_menu_file_pos = i;
420
421 if (item[i][0] == '1')
422 item[i][0] = 'D';
423 else if (item[i][0] == '2')
424 item[i][0] = 'L';
425 else if (item[i][0] == '3')
426 item[i][0] = ' ';
427 }
428 }
429 else
430 printf("Error: can't open directory\r\n");
431
432 if (pro_menu_file_pos>MENU_AH-1)
433 pro_menu_file_start = pro_menu_file_pos - MENU_AH + 1;
434 else
435 pro_menu_file_start = 0;
436
437 pro_menu_pos = pro_menu_file_pos;
438 pro_menu_start = pro_menu_file_start;
439
440 pro_menu_print(pro_menu_start);
441 pro_menu_bar(pro_menu_pos-pro_menu_start);
442 }
443
444
445 /* Initialize and print serial menu */
446
pro_menu_serial(struct sercall ** porttype,int port)447 void pro_menu_serial (struct sercall **porttype, int port)
448 {
449 int i;
450
451
452 for(i=0; i<MENU_SERIAL_NUM; i++)
453 item_ok[i] = 1;
454
455 pro_menu_serial_pos = pro_menu_print_serial(item[0], "", *porttype, port);
456 if (pro_menu_serial_pos>(MENU_AH-1))
457 pro_menu_serial_start = pro_menu_serial_pos - MENU_AH + 1;
458 else
459 pro_menu_serial_start = 0;
460
461 /* Disable in-use ports from selection */
462
463 if ((porttype != &pro_com) && (pro_com != &pro_null))
464 item_ok[pro_menu_print_serial(item[0], "", pro_com, pro_com_port)] = 0;
465
466 if ((porttype != &pro_ptr) && (pro_ptr != &pro_null))
467 item_ok[pro_menu_print_serial(item[0], "", pro_ptr, pro_ptr_port)] = 0;
468
469 if ((porttype != &pro_kb_orig) && (pro_kb_orig != &pro_null))
470 item_ok[pro_menu_print_serial(item[0], "", pro_kb_orig, pro_kb_port)] = 0;
471
472 if ((porttype != &pro_la50device) && (pro_la50device != &pro_null))
473 item_ok[pro_menu_print_serial(item[0], "", pro_la50device, pro_la50device_port)] = 0;
474
475 pro_menu_active = MENU_SERIAL;
476 pro_menu_start = pro_menu_serial_start;
477 pro_menu_pos = pro_menu_serial_pos;
478 pro_menu_items = MENU_SERIAL_NUM;
479
480 if (porttype == &pro_com)
481 sprintf(title, "Communications Port");
482 else if (porttype == &pro_ptr)
483 sprintf(title, "Printer Port");
484 else if (porttype == &pro_kb_orig)
485 sprintf(title, "Keyboard Port");
486
487 pro_menu_print_serial(item[0], "", &pro_serial, 0);
488 pro_menu_print_serial(item[1], "", &pro_serial, 1);
489 pro_menu_print_serial(item[2], "", &pro_serial, 2);
490 pro_menu_print_serial(item[3], "", &pro_serial, 3);
491 pro_menu_print_serial(item[4], "", &pro_digipad, 0);
492 pro_menu_print_serial(item[5], "", &pro_lk201, 0);
493 pro_menu_print_serial(item[6], "", &pro_la50, 0);
494 pro_menu_print_serial(item[7], "", &pro_null, 0);
495
496 pro_menu_print(pro_menu_start);
497 pro_menu_bar(pro_menu_pos-pro_menu_start);
498 }
499
500
501 /* Initialize and print "about XHOMER" page */
502
pro_menu_about()503 void pro_menu_about ()
504 {
505 int i;
506
507
508 for(i=0; i<MENU_ABOUT_NUM; i++)
509 item_ok[i] = 1;
510
511 pro_menu_active = MENU_ABOUT;
512 pro_menu_start = 0;
513 pro_menu_pos = MENU_ABOUT_NUM - 1;
514 pro_menu_items = MENU_ABOUT_NUM;
515
516 sprintf(title, "About XHOMER");
517
518 sprintf(item[0], "Welcome to XHOMER, a Digital");
519 sprintf(item[1], "Pro/350 machine emulator,");
520 sprintf(item[2], "written by Tarik Isani. This");
521 sprintf(item[3], "emulator is based on a");
522 sprintf(item[4], "slightly modified version of");
523 sprintf(item[5], "the PDP-11 CPU core from the");
524 sprintf(item[6], "SIMH simulator. Download from");
525 sprintf(item[7], "http://xhomer.isani.org/");
526 sprintf(item[8], " ");
527 sprintf(item[9], "Please direct any questions or");
528 sprintf(item[10], "feedback to: xhomer@isani.org");
529 sprintf(item[11], " ");
530 sprintf(item[12], "Previous menu");
531
532 pro_menu_print(pro_menu_start);
533 pro_menu_bar(pro_menu_pos-pro_menu_start);
534 }
535
536
537 /* Initialize and print top-level menu */
538
pro_menu_top()539 void pro_menu_top ()
540 {
541 int i;
542
543 for(i=0; i<MENU_AW+2*MENU_BW-2; i++)
544 menu_bar[i] = ' ';
545 menu_bar[i] = '\0';
546
547 for(i=0; i<MENU_TOP_NUM; i++)
548 item_ok[i] = 1;
549
550 item_ok[MENU_TOP_RD0] = 0;
551 item_ok[MENU_TOP_SAVE] = 0;
552 item_ok[MENU_TOP_REST] = 0;
553 item_ok[MENU_TOP_RESET] = 0;
554
555 pro_menu_active = MENU_TOP;
556 pro_menu_start = pro_menu_top_start;
557 pro_menu_pos = pro_menu_top_pos;
558 pro_menu_items = MENU_TOP_NUM;
559 pro_menu_on = 1;
560 pro_overlay_enable();
561
562 sprintf(title, "XHOMER (version %s)", PRO_VERSION);
563 sprintf(item[0], "Return to emulator");
564 sprintf(item[1], "Screen mode : %s", pro_screen_full?"full":"window");
565 pro_menu_concat(item[2], "rx0 : ", pro_rx_file[0], MENU_AW);
566 pro_menu_concat(item[3], "rx1 : ", pro_rx_file[1], MENU_AW);
567 pro_menu_concat(item[4], "rd0 : ", pro_rd_file, MENU_AW);
568 pro_menu_print_serial(item[5], "com : ", pro_com, pro_com_port);
569 pro_menu_print_serial(item[6], "ptr : ", pro_ptr, pro_ptr_port);
570 pro_menu_print_serial(item[7], "kb : ", pro_kb_orig, pro_kb_port);
571 sprintf(item[8], "Save configuration");
572 sprintf(item[9], "Restore defaults and reset");
573 sprintf(item[10], "Reset");
574 sprintf(item[11], "About XHOMER");
575 sprintf(item[12], "Shutdown emulator");
576
577 pro_menu_print(pro_menu_start);
578 pro_menu_bar(pro_menu_pos-pro_menu_start);
579 }
580
581
582 /* This routine filters keyboard characters
583 Any characters which are not menu commands are passed through */
584
pro_menu(int key)585 int pro_menu (int key)
586 {
587 int retchar, schar, menu_pos_old;
588
589 retchar = key;
590 schar = key;
591
592 /* Handle auto-repeat from real LK201 */
593
594 if (schar == PRO_LK201_REPEAT)
595 schar = pro_menu_last_char;
596 else
597 pro_menu_last_char = schar;
598
599 if (schar == PRO_LK201_CTRL)
600 pro_menu_key_ctrl = 1;
601 else if (schar == PRO_LK201_ALLUPS)
602 pro_menu_key_ctrl = 0;
603 else if ((schar == PRO_LK201_DEL) && (pro_menu_key_ctrl == 1))
604 pro_exit();
605 else if (pro_menu_on == 1)
606 {
607 /* Process menu commands */
608
609 menu_pos_old = pro_menu_pos;
610
611 if (schar == PRO_LK201_UP)
612 {
613 /* Scroll menu bar up */
614
615 if (pro_menu_pos > 0)
616 {
617 pro_menu_bar(pro_menu_pos-pro_menu_start);
618
619 do
620 pro_menu_pos--;
621 while ((pro_menu_pos > 0) && (item_ok[pro_menu_pos] == 0));
622
623 if (item_ok[pro_menu_pos] == 0)
624 pro_menu_pos = menu_pos_old;
625
626 if (pro_menu_pos<pro_menu_start)
627 {
628 pro_menu_start = pro_menu_pos;
629 pro_menu_print(pro_menu_start);
630 }
631 pro_menu_bar(pro_menu_pos-pro_menu_start);
632 }
633 retchar = PRO_NOCHAR;
634 }
635 else if (schar == PRO_LK201_DOWN)
636 {
637 /* Scroll menu bar down */
638
639 if (pro_menu_pos < (pro_menu_items-1))
640 {
641 pro_menu_bar(pro_menu_pos-pro_menu_start);
642
643 do
644 pro_menu_pos++;
645 while ((pro_menu_pos < (pro_menu_items-1)) && (item_ok[pro_menu_pos] == 0));
646
647 if (item_ok[pro_menu_pos] == 0)
648 pro_menu_pos = menu_pos_old;
649
650 if (pro_menu_pos>pro_menu_start+MENU_AH-1)
651 {
652 pro_menu_start = pro_menu_pos - MENU_AH + 1;
653 pro_menu_print(pro_menu_start);
654 }
655 pro_menu_bar(pro_menu_pos-pro_menu_start);
656 }
657 retchar = PRO_NOCHAR;
658 }
659 else if ((schar == PRO_LK201_RETURN) || (schar == PRO_LK201_DO))
660 {
661 if (pro_menu_active == MENU_TOP)
662 {
663 /* Execute menu item */
664
665 pro_menu_top_start = pro_menu_start;
666 pro_menu_top_pos = pro_menu_pos;
667
668 switch (pro_menu_pos)
669 {
670 case MENU_TOP_RETURN:
671 /* Turn off menu */
672
673 pro_menu_on = 0;
674 pro_overlay_disable();
675 break;
676
677 case MENU_TOP_SCREEN:
678 /* Switch screen mode */
679
680 pro_screen_close();
681
682 if (pro_screen_full == 0)
683 pro_screen_full = 1;
684 else
685 pro_screen_full = 0;
686
687 if (pro_screen_init() == PRO_FAIL)
688 {
689 /* Switch mode back */
690
691 pro_screen_close();
692
693 if (pro_screen_full == 0)
694 pro_screen_full = 1;
695 else
696 pro_screen_full = 0;
697
698 pro_screen_init();
699 }
700
701 pro_menu_top();
702 break;
703
704 case MENU_TOP_RX0:
705 case MENU_TOP_RX1:
706 /* Floppy 0, 1 */
707
708 /* Open floppy door */
709
710 pro_rx_open_door(pro_menu_pos-MENU_TOP_RX0);
711
712 pro_menu_file(&pro_rx_file[pro_menu_pos-MENU_TOP_RX0]);
713 break;
714
715 case MENU_TOP_RD0:
716 /* Hard disk 0 */
717
718 pro_menu_file(&pro_rd_file);
719 break;
720
721 case MENU_TOP_COM:
722 /* com menu */
723
724 pro_menu_serial(&pro_com, pro_com_port);
725 break;
726
727 case MENU_TOP_PTR:
728 /* ptr menu */
729
730 pro_menu_serial(&pro_ptr, pro_ptr_port);
731 break;
732
733 case MENU_TOP_KB:
734 /* kb menu */
735
736 pro_menu_serial(&pro_kb_orig, pro_kb_port);
737 break;
738
739 case MENU_TOP_ABOUT:
740 pro_menu_about();
741 break;
742
743 case MENU_TOP_SHUT:
744 pro_exit();
745 break;
746
747 default:
748 break;
749 }
750 }
751 else if (pro_menu_active == MENU_SERIAL)
752 {
753 switch (pro_menu_top_pos)
754 {
755 case MENU_TOP_COM:
756 pro_com_exit();
757 pro_menu_assign_serial(pro_menu_pos, &pro_com, &pro_com_port);
758 pro_com_open();
759 break;
760
761 case MENU_TOP_PTR:
762 pro_ptr_exit();
763 pro_menu_assign_serial(pro_menu_pos, &pro_ptr, &pro_ptr_port);
764 pro_ptr_open();
765 break;
766
767 case MENU_TOP_KB:
768 pro_kb_exit();
769 pro_menu_assign_serial(pro_menu_pos, &pro_kb, &pro_kb_port);
770 pro_kb_open();
771 break;
772
773 default:
774 break;
775 }
776
777 pro_menu_top();
778 }
779 else if (pro_menu_active == MENU_FILE)
780 {
781 switch (pro_menu_top_pos)
782 {
783 case MENU_TOP_RX0:
784 case MENU_TOP_RX1:
785 /* Check if directory, file or none */
786
787 if (item[pro_menu_pos][0] == 'D')
788 {
789 /* Update directory name */
790
791 pro_menu_newdir(&pro_rx_dir[pro_menu_top_pos-MENU_TOP_RX0], item[pro_menu_pos]+2);
792 pro_menu_file(&pro_rx_file[pro_menu_top_pos-MENU_TOP_RX0]);
793 }
794 else
795 {
796 /* Update file name */
797
798 if (pro_rx_file[pro_menu_top_pos-MENU_TOP_RX0] != NULL)
799 free(pro_rx_file[pro_menu_top_pos-MENU_TOP_RX0]);
800
801 pro_rx_file[pro_menu_top_pos-MENU_TOP_RX0] = strdup(item[pro_menu_pos]+2);
802
803 /* Close floppy door */
804
805 /* Check if no image */
806
807 if (pro_menu_pos != 0)
808 pro_rx_close_door(pro_menu_top_pos-MENU_TOP_RX0);
809 pro_menu_top();
810 }
811 break;
812
813 case MENU_TOP_RD0:
814 pro_menu_top();
815 break;
816
817 default:
818 break;
819 }
820 }
821 else if (pro_menu_active == MENU_ABOUT)
822 {
823 if (pro_menu_pos == (MENU_ABOUT_NUM-1))
824 pro_menu_top();
825 }
826
827 retchar = PRO_NOCHAR;
828 }
829 }
830 else if ((schar == PRO_LK201_PRINT) && (pro_menu_key_ctrl == 1))
831 {
832 /* Turn on top-level menu */
833
834 pro_menu_top();
835
836 pro_menu_top_start = 0;
837 pro_menu_top_pos = 0;
838
839 retchar = PRO_NOCHAR;
840 }
841
842 return retchar;
843 }
844
845
846 /* Reset menu subsystem */
847
pro_menu_reset()848 void pro_menu_reset ()
849 {
850 pro_menu_last_char = 0;
851 pro_menu_key_ctrl = 0;
852 pro_menu_on = 0;
853 }
854 #endif
855