Save/restore registers to host during memory operations. Cache ROM data.
[fw/altos] / s51 / s51-main.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "s51.h"
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <signal.h>
25 #include <stdarg.h>
26 #include <poll.h>
27
28 static int s51_port = 0;
29 static char *cpu = "8051";
30 static double freq = 11059200;
31 char *s51_prompt = "> ";
32 struct ccdbg *s51_dbg;
33 int s51_interrupted = 0;
34 int s51_monitor = 0;
35
36 static FILE *s51_input;
37 static FILE *s51_output;
38
39 static void
40 usage(void)
41 {
42         fprintf(stderr, "You're doing it wrong.\n");
43         exit(1);
44 }
45
46 void s51_sigint()
47 {
48         s51_interrupted = 1;
49 }
50
51 int
52 main(int argc, char **argv)
53 {
54         int flags, opt;
55         char *endptr;
56         struct sigvec vec, ovec;
57
58         while ((opt = getopt(argc, argv, "PVvHhmt:X:c:r:Z:s:S:p:")) != -1) {
59                 switch (opt) {
60                 case 't':
61                         cpu = optarg;
62                         break;
63                 case 'X':
64                         freq = strtod(optarg, &endptr);
65                         if (endptr == optarg)
66                                 usage();
67                         if (endptr[0] != '\0') {
68                                 if (!strcmp(endptr, "k"))
69                                         freq *= 1000;
70                                 else if (!strcmp(endptr, "M") )
71                                         freq *= 1000000;
72                                 else
73                                         usage ();
74                         }
75                         break;
76                 case 'c':
77                         break;
78                 case 'r':
79                 case 'Z':
80                         s51_port = strtol(optarg, &endptr, 0);
81                         if (endptr == optarg || strlen(endptr) != 0)
82                                 usage();
83                         break;
84                 case 's':
85                         break;
86                 case 'S':
87                         break;
88                 case 'p':
89                         s51_prompt = optarg;
90                         break;
91                 case 'P':
92                         s51_prompt = NULL;
93                         break;
94                 case 'V':
95                         break;
96                 case 'v':
97                         break;
98                 case 'H':
99                         exit (0);
100                         break;
101                 case 'h':
102                         usage ();
103                         break;
104                 case 'm':
105                         s51_monitor = 1;
106                         break;
107                 }
108         }
109         if (s51_port) {
110                 int l, r, one = 1;
111                 int s;
112                 struct sockaddr_in in;
113
114                 l = socket(AF_INET, SOCK_STREAM, 0);
115                 if (l < 0) {
116                         perror ("socket");
117                         exit(1);
118                 }
119                 r = setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (int));
120                 if (r) {
121                         perror("setsockopt");
122                         exit(1);
123                 }
124                 in.sin_family = AF_INET;
125                 in.sin_port = htons(s51_port);
126                 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
127                 r = bind(l, (struct sockaddr *) &in, sizeof (in));
128                 if (r) {
129                         perror("bind");
130                         exit(1);
131                 }
132                 r = listen(l, 5);
133                 if (r) {
134                         perror("listen");
135                         exit(1);
136                 }
137                 for (;;) {
138                         struct sockaddr_in client_addr;
139                         socklen_t client_len = sizeof (struct sockaddr_in);
140                         
141                         s = accept(l, (struct sockaddr *)
142                                    &client_addr, &client_len);
143                         if (s < 0) {
144                                 perror("accept");
145                                 exit(1);
146                         }
147                         s51_input = fdopen(s, "r");
148                         s51_output = fdopen(s, "w");
149                         if (!s51_input || !s51_output) {
150                                 perror("fdopen");
151                                 exit(1);
152                         }
153                         vec.sv_handler = s51_sigint;
154                         vec.sv_mask = 0;
155                         vec.sv_flags = 0;
156                         sigvec(SIGINT, &vec, &ovec);
157                         command_read();
158                         sigvec(SIGINT, &ovec, NULL);
159                         fclose(s51_input);
160                         fclose(s51_output);
161                 }
162         } else {
163                 s51_input = stdin;
164                 s51_output = stdout;
165                 vec.sv_handler = s51_sigint;
166                 vec.sv_mask = 0;
167                 vec.sv_flags = 0;
168                 sigvec(SIGINT, &vec, &ovec);
169                 command_read();
170         }
171         exit(0);
172 }
173
174 void
175 s51_printf(char *format, ...)
176 {
177         va_list ap;
178
179         va_start(ap, format);
180         vfprintf(s51_output, format, ap);
181         if (s51_monitor)
182                 vfprintf(stdout, format, ap);
183         va_end(ap);
184 }
185
186 void
187 s51_putc(int c)
188 {
189         putc(c, s51_output);
190 }
191
192 int
193 s51_read_line(char *line, int len)
194 {
195         int ret;
196         if (s51_prompt)
197                 s51_printf("%s", s51_prompt);
198         else
199                 s51_putc('\0');
200         fflush(s51_output);
201         ret = fgets(line, len, s51_input) != NULL;
202         if (s51_monitor)
203                 printf("> %s", line);
204         fflush(stdout);
205         return ret;
206 }
207
208 int
209 s51_check_input(void)
210 {
211         struct pollfd   input;
212         int r;
213         int c;
214
215         input.fd = fileno(s51_input);
216         input.events = POLLIN;
217         r = poll(&input, 1, 0);
218         if (r > 0) {
219                 char line[256];
220                 (void) s51_read_line(line, sizeof (line));
221                 return 1; 
222         }
223         return 0;
224 }
225