|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
1.1.1.2 root 3: *
1.1 root 4: * pos-rexx.c
1.1.1.2 root 5: *
1.1 root 6: * Copyright 1997 Samuel Devulder.
7: */
8:
9: int rexx_init(void);
10: void rexx_exit(void);
11: void rexx_led(int led, int on);
12: void rexx_filename(int num, char *name);
13: void rexx_handle_events(void);
14:
15: int rexx_init(void) {return 0;}
16: void rexx_exit(void) {}
17: void rexx_led(int led, int on) {}
18: void rexx_filename(int num, char *name) {}
19: void rexx_handle_events(void) {}
20:
21: #if 0 /* nothing yet on pOS for rexx */
22:
23: #include <proto/exec.h>
24: #include <proto/alib.h>
25: #include <proto/rexxsyslib.h>
26: #include <proto/dos.h>
27:
28: #include <rexx/storage.h>
29: #include <rexx/errors.h>
30:
31: /* this prevent a conflict between <rexx/rexxio.h> and <sys/dirent.h> */
1.1.1.2 root 32: #undef DT_DIR
1.1 root 33:
34: /****************************************************************************/
35:
36: #include "sysconfig.h"
37: #include "sysdeps.h"
38:
39: #include "uae.h"
40: #include "options.h"
41: #include "../include/memory.h" /* or else gcc includes machdep/memory.h */
42: #include "custom.h"
43: #include "readcpu.h"
44: #include "newcpu.h"
45: #include "disk.h"
46: #include "gui.h"
47: #include "os.h"
48:
49: #include <ctype.h>
50:
51: /****************************************************************************/
52:
53: #define UAE_PORTNAME "UAE"
54: #define RESULT_LEN 1024
55: #define PORT_LEN 80
56: #define CMD_LEN 1024
57:
58: typedef struct
59: {
60: char port[PORT_LEN];
61: char cmd_on[CMD_LEN];
62: char cmd_off[CMD_LEN];
63: } gui_rexx_s;
64:
65: enum {LED_POW, LED_DF0, LED_DF1, LED_DF2, LED_DF3,
66: NAME_DF0, NAME_DF1, NAME_DF2, NAME_DF3,
67: ON_EXIT,
68: GUI_REXX_MAX};
69:
70: /****************************************************************************/
71:
72: int rexx_init(void);
73: void rexx_exit(void);
74: void rexx_led(int led, int on);
75: void rexx_filename(int num, char *name);
76: void rexx_handle_events(void);
77:
78: /****************************************************************************/
79:
80: struct /*RxsLib*/ Library
1.1.1.2 root 81: *RexxSysBase;
1.1 root 82: static struct MsgPort *ARexxPort;
83: static gui_rexx_s gui_rexx[GUI_REXX_MAX];
84: static char RESULT[RESULT_LEN];
85: static int led_state[5];
86:
87: static int ADDRESS(char *hostname, char *cmd);
88: static int matchstr(char **line,char *pat);
89: static void extractstr(char **line, char *result, int len);
90: static int matchnum(char **line);
91:
92: /****************************************************************************/
93:
94: extern int quit_program; /* ami-gui.c */
95: extern void activate_debugger(void); /* debug.c */
96: extern char *to_unix_path(char *s); /* ami-disk.c */
97: extern char *from_unix_path(char *s); /* ami-disk.c */
98:
99: /****************************************************************************/
100:
101: int rexx_init(void)
102: {
103: quit_program = 0;
104: RexxSysBase = (void*)OpenLibrary("rexxsyslib.library",0L);
105: if(!RexxSysBase) {
1.1.1.2 root 106: fprintf(stderr, "Can't find rexxsyslib.library!\n");
107: return 1;
1.1 root 108: }
109: if(FindPort(UAE_PORTNAME)) {
1.1.1.2 root 110: fprintf(stderr, "Port \"%s\" already exists!\n",UAE_PORTNAME);
111: return 1;
1.1 root 112: }
113: ARexxPort = CreatePort(UAE_PORTNAME,0);
114: if(!ARexxPort) {
1.1.1.2 root 115: fprintf(stderr, "Failed to open AREXX port \"%s\"!\n",UAE_PORTNAME);
116: return 1;
1.1 root 117: }
118: fprintf(stderr,"Rexx port \"%s\" installed.\n", UAE_PORTNAME);
119: rexx_handle_events();
120: return 0;
121: }
122:
123: /****************************************************************************/
124:
125: void rexx_exit(void)
126: {
127: if(ARexxPort) {
1.1.1.2 root 128: struct RexxMsg *msg;
129: gui_rexx_s *gui = &gui_rexx[ON_EXIT];
1.1 root 130:
1.1.1.2 root 131: if(gui->port[0] && gui->cmd_on[0]) {
132: if(ADDRESS(gui->port, gui->cmd_on) != RC_OK) {
133: fprintf(stderr,"%s:%s:%s\n", gui->port,
134: gui->cmd_on,
135: RESULT);
136: }
137: gui->port[0] = '\0';
138: }
139: Forbid();
140: while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
141: msg->rm_Result1 = RC_ERROR;
142: msg->rm_Result2 = NULL;
143: ReplyMsg((void*)msg);
144: }
145: DeletePort(ARexxPort);
146: Permit();
147: ARexxPort = NULL;
1.1 root 148: }
149: if(RexxSysBase) {
1.1.1.2 root 150: CloseLibrary((void*)RexxSysBase);
151: RexxSysBase = NULL;
1.1 root 152: }
153: }
154:
155: /****************************************************************************/
156:
157: static int EJECT(char *line)
158: {
159: int drive = matchnum(&line);
160: if(drive<0 || drive>3) return RC_WARN;
161: disk_eject(drive);
162: sprintf(RESULT,"Drive %d ejected",drive);
163: return RC_OK;
164: }
165:
166: /****************************************************************************/
167:
168: static int INSERT(char *line)
169: {
170: int drive = matchnum(&line);
171: if(drive<0 || drive>3) return RC_WARN;
172: if(disk_empty(drive)) {
1.1.1.2 root 173: char buff[256];
174: char *name;
175: extractstr(&line, buff, 256);
176: name = to_unix_path(buff);
177: disk_insert(drive, name);
178: free(name);
1.1 root 179: } else {
1.1.1.2 root 180: sprintf(RESULT,"Drive %d not empty!",drive);
181: return RC_WARN;
1.1 root 182: }
183: return RC_OK;
184: }
185:
186: /****************************************************************************/
187:
188: static void QUIT(void)
189: {
190: broken_in = 1;
191: regs.spcflags |= SPCFLAG_BRK;
192: quit_program = 1;
193: }
194:
195: /****************************************************************************/
196:
197: static int QUERY(char *line)
198: {
199: char *res = NULL;
200: int alc = 0;
201:
202: if (matchstr(&line, "LED_POW")) res = led_state[0]?"1":"0";
203: else if(matchstr(&line, "LED_DF0")) res = led_state[1]?"1":"0";
204: else if(matchstr(&line, "LED_DF1")) res = led_state[2]?"1":"0";
205: else if(matchstr(&line, "LED_DF2")) res = led_state[3]?"1":"0";
206: else if(matchstr(&line, "LED_DF3")) res = led_state[4]?"1":"0";
207: else if(matchstr(&line, "NAME_DF0")) res = from_unix_path(df0), alc = 1;
208: else if(matchstr(&line, "NAME_DF1")) res = from_unix_path(df1), alc = 1;
209: else if(matchstr(&line, "NAME_DF2")) res = from_unix_path(df2), alc = 1;
210: else if(matchstr(&line, "NAME_DF3")) res = from_unix_path(df3), alc = 1;
211: else if(matchstr(&line, "FAKEJOYSTICK")) res = fake_joystick?"1":"0";
212: else if(matchstr(&line, "DISPLAY")) res = inhibit_frame?"0":"1";
213: else if(matchstr(&line, "FRAMERATE")) {
1.1.1.2 root 214: sprintf(RESULT,"%d",framerate);
215: return RC_OK;
1.1 root 216: } else if(matchstr(&line, "SOUND")) {
1.1.1.2 root 217: sprintf(RESULT,"%d",sound_available?produce_sound:-1);
218: return RC_OK;
219: }
1.1 root 220: else return RC_ERROR;
221:
222: if(res) {
1.1.1.2 root 223: strncpy(RESULT, res, RESULT_LEN);
224: if(alc) free(res);
1.1 root 225: }
226: return RC_OK;
227: }
228:
229: /****************************************************************************/
230:
231: static int FEEDBACK(char *line)
232: {
233: gui_rexx_s *gui = NULL;
234:
235: if (matchstr(&line,"LED_POW")) gui = &gui_rexx[LED_POW];
236: else if(matchstr(&line,"LED_DF0")) gui = &gui_rexx[LED_DF0];
237: else if(matchstr(&line,"LED_DF1")) gui = &gui_rexx[LED_DF1];
238: else if(matchstr(&line,"LED_DF2")) gui = &gui_rexx[LED_DF2];
239: else if(matchstr(&line,"LED_DF3")) gui = &gui_rexx[LED_DF3];
240: else if(matchstr(&line,"NAME_DF0")) gui = &gui_rexx[NAME_DF0];
241: else if(matchstr(&line,"NAME_DF1")) gui = &gui_rexx[NAME_DF1];
242: else if(matchstr(&line,"NAME_DF2")) gui = &gui_rexx[NAME_DF2];
243: else if(matchstr(&line,"NAME_DF3")) gui = &gui_rexx[NAME_DF3];
244: else if(matchstr(&line,"ON_EXIT")) gui = &gui_rexx[ON_EXIT];
245: else return RC_ERROR;
246:
247: while(1) {
1.1.1.2 root 248: if(matchstr(&line, "ADDRESS") ||
249: matchstr(&line, "PORT")) {
250: extractstr(&line, gui->port, PORT_LEN);
251: } else if(matchstr(&line,"COMMAND") ||
252: matchstr(&line,"CMD") ||
253: matchstr(&line,"CMD_ON")) {
254: extractstr(&line, gui->cmd_on, CMD_LEN);
255: } else if(matchstr(&line,"CMD_OFF")) {
256: extractstr(&line, gui->cmd_off, CMD_LEN);
257: } else break;
1.1 root 258: }
259: return RC_OK;
260: }
261:
262: /****************************************************************************/
263:
264: static int VERSION(char *line)
265: {
266: if(matchstr(&line,"STRING")) {
1.1.1.2 root 267: sprintf(RESULT,
268: "UAE-%d.%d.%d � by Bernd Schmidt & contributors, "
269: "Amiga Port by Samuel Devulder.",
270: (version / 100) % 10, (version / 10) % 10, version % 10);
1.1 root 271: } else if(matchstr(&line,"NUM")) {
1.1.1.2 root 272: sprintf(RESULT,"%d",version);
1.1 root 273: } else if(matchstr(&line,"AUTHOR")) {
1.1.1.2 root 274: sprintf(RESULT,"� by Bernd Schmidt & contributors");
1.1 root 275: } else if(matchstr(&line,"PORT")) {
1.1.1.2 root 276: sprintf(RESULT,"Amiga Port by Samuel Devulder");
1.1 root 277: } else return RC_ERROR;
278: return RC_OK;
279: }
280:
281: /****************************************************************************/
282:
283: static int FRAMERATE(char *line)
284: {
285: int num;
286: num = matchnum(&line);
287: if(num>=1 && num<=20) {
1.1.1.2 root 288: framerate = num;
1.1 root 289: } else {
1.1.1.2 root 290: sprintf(RESULT,"Invalid frame rate: %d\n", num);
291: return RC_WARN;
1.1 root 292: }
293: return RC_OK;
294: }
295:
296: /****************************************************************************/
297:
298: static int FAKEJOYSTICK(char *line)
299: {
300: if (matchstr(&line,"ON")) fake_joystick = 1;
301: else if(matchstr(&line,"OFF")) fake_joystick = 0;
302: else if(matchstr(&line,"TOGGLE")) fake_joystick = fake_joystick?0:1;
303: else return RC_ERROR;
304: return RC_OK;
305: }
306:
307: /****************************************************************************/
308:
309: static int DISPLAY(char *line)
310: {
311: if (matchstr(&line,"ON")) inhibit_frame = 0;
312: else if(matchstr(&line,"OFF")) inhibit_frame = 1;
313: else if(matchstr(&line,"TOGGLE")) inhibit_frame = inhibit_frame?0:1;
314: else return RC_ERROR;
315: return RC_OK;
316: }
317:
318: /****************************************************************************/
319:
320: static int SOUND(char *line)
321: {
322: if(!sound_available) {
1.1.1.2 root 323: sprintf(RESULT,"Sound not available!");
324: return RC_WARN;
1.1 root 325: }
326:
327: if (matchstr(&line,"ON")) produce_sound = 2;
328: else if(matchstr(&line,"OFF")) produce_sound = 1;
329: else if(matchstr(&line,"BEST")) produce_sound = 3;
330: else if(matchstr(&line,"TOGGLE")) produce_sound = produce_sound<=1?2:1;
331: else return RC_ERROR;
332: return RC_OK;
333: }
334:
335: /****************************************************************************/
336:
337: static int process_cmd(char *line)
338: {
339: RESULT[0] = '\0';
340: if (matchstr(&line, "EJECT")) return EJECT(line);
341: else if(matchstr(&line, "INSERT")) return INSERT(line);
342: else if(matchstr(&line, "QUERY")) return QUERY(line);
343: else if(matchstr(&line, "FEEDBACK")) return FEEDBACK(line);
344: else if(matchstr(&line, "VERSION")) return VERSION(line);
345: else if(matchstr(&line, "BYE")) QUIT();
346: else if(matchstr(&line, "QUIT")) QUIT();
347: else if(matchstr(&line, "DEBUG")) activate_debugger();
348: else if(matchstr(&line, "RESET")) m68k_reset();
349: else if(matchstr(&line, "DISPLAY")) return DISPLAY(line);
350: else if(matchstr(&line, "FRAMERATE")) return FRAMERATE(line);
351: else if(matchstr(&line, "FAKEJOYSTICK")) return FAKEJOYSTICK(line);
352: else if(matchstr(&line, "SOUND")) return SOUND(line);
353: else return RC_ERROR;
354: return RC_OK;
355: }
356:
357: /****************************************************************************/
358:
359: void rexx_handle_events(void)
360: {
361: struct RexxMsg *msg;
362: while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
1.1.1.2 root 363: if(!(msg->rm_Action & RXCOMM)) {
364: fprintf(stderr,"Unknown action '%08X' recieved!\n",
365: msg->rm_Action);
366: continue;
367: }
368: msg->rm_Result1 = process_cmd(msg->rm_Args[0]);
369: msg->rm_Result2 = NULL;
370: if(msg->rm_Action & RXFF_RESULT) {
371: msg->rm_Result2 = (LONG)CreateArgstring(RESULT,strlen(RESULT));
372: }
373: ReplyMsg((void*)msg);
1.1 root 374: }
375: }
376:
377: /****************************************************************************/
378:
379: void rexx_led(int led, int on)
380: {
381: gui_rexx_s *gui = NULL;
382:
383: if(led < 0 || led > 4) return;
384: led_state[led] = on;
385:
386: if(led == 0) gui = &gui_rexx[LED_POW];
387: if(led == 1) gui = &gui_rexx[LED_DF0];
388: if(led == 2) gui = &gui_rexx[LED_DF1];
389: if(led == 3) gui = &gui_rexx[LED_DF2];
390: if(led == 4) gui = &gui_rexx[LED_DF3];
391:
392: if(gui->port[0] && gui->cmd_on[0] && gui->cmd_off[0]) {
1.1.1.2 root 393: if(ADDRESS(gui->port, on ? gui->cmd_on : gui->cmd_off) != RC_OK) {
394: fprintf(stderr,"%s:%s:%s\n", gui->port,
395: on ? gui->cmd_on : gui->cmd_off,
396: RESULT);
397: }
1.1 root 398: }
399: }
400:
401: /****************************************************************************/
402:
403: void rexx_filename(int num, char *filename)
404: {
405: gui_rexx_s *gui = NULL;
406: if(num < 0 || num > 3) return;
407: gui = &gui_rexx[NAME_DF0 + num];
408: if(gui->port[0] && gui->cmd_on[0]) {
1.1.1.2 root 409: char buf[CMD_LEN];
410: if(!(filename = from_unix_path(filename))) return;
411: sprintf(buf, gui->cmd_on, filename);
412: free(filename);
413: if(ADDRESS(gui->port, buf) != RC_OK) {
414: fprintf(stderr,"%s:%s:%s\n", gui->port, buf, RESULT);
415: }
1.1 root 416: }
417: }
418:
419: /****************************************************************************/
420: /* send a message to an AREXX port.
421: */
422: static int ADDRESS(char *hostname, char *cmd)
423: {
424: struct MsgPort *RexxPort,
1.1.1.2 root 425: *ReplyPort;
1.1 root 426: struct RexxMsg *HostMsg,
1.1.1.2 root 427: *answer;
1.1 root 428: int result = RC_WARN;
429:
430: if(!stricmp(hostname, "COMMAND")) {
1.1.1.2 root 431: return SystemTagList(cmd,NULL);
1.1 root 432: }
433:
434: if((RexxPort = (void *)FindPort(hostname))) {
1.1.1.2 root 435: if((ReplyPort = (void *)CreateMsgPort())) {
436: if((HostMsg = CreateRexxMsg(ReplyPort, NULL, hostname))) {
437: if((HostMsg->rm_Args[0] = CreateArgstring(cmd,strlen(cmd)))) {
438: HostMsg->rm_Action = RXCOMM | RXFF_RESULT;
439: PutMsg(RexxPort, (void*)HostMsg);
440: WaitPort(ReplyPort);
441: while(!(answer = (void *)GetMsg(ReplyPort)));
442: result = answer->rm_Result1;
443: if(result == RC_OK) {
444: if(answer->rm_Result2) {
445: strncpy(RESULT,(char *)answer->rm_Result2,RESULT_LEN);
446: DeleteArgstring((char *)answer->rm_Result2);
447: } else RESULT[0] = '\0';
448: }
449: DeleteArgstring(HostMsg->rm_Args[0]);
450: } else strcpy(RESULT, "Can't create argstring!");
451: DeleteRexxMsg(HostMsg);
452: } else strcpy(RESULT, "Can't create rexx message!");
453: DeleteMsgPort(ReplyPort);
454: } else strcpy(RESULT, "Can't alloc reply port!");
1.1 root 455: } else sprintf(RESULT, "Port \"%s\" not found!",hostname);
456: return result;
457: }
458:
459: /****************************************************************************/
460: /* argument parsing routines
461: */
462: static int matchstr(char **line,char *pat)
463: {
464: char *s = *line;
465: char match = 0;
466: while(isspace(*s)) ++s;
467: if(*s=='\"' || *s== '\'') match = *s++;
468: while(*s && (tolower(*s)==tolower(*pat)) && (!match || *s!=match)) {++s;++pat;}
469: if(match && *s==match && s[1]) ++s;
470: if(!*pat && (!*s || isspace(*s))) {
1.1.1.2 root 471: while(isspace(*s)) ++s;
472: *line = s;
473: return 1;
1.1 root 474: }
475: return 0;
476: }
477:
478: /****************************************************************************/
479:
480: static void extractstr(char **line, char *result, int len)
481: {
482: char *s = *line;
483: char match = 0;
484:
485: while(isspace(*s)) ++s;
486:
487: if(*s=='\"' || *s=='\'') match = *s++;
488: while(*s && *s != match) {
1.1.1.2 root 489: if(*s == '\\' && (s[1] == '\'' || s[1] == '\"')) ++s;
490: if(len > 1) {*result++ = *s;--len;}
491: ++s;
492: if(!match && isspace(*s)) break;
1.1 root 493: }
494: if(match && *s == match) ++s;
495: while(isspace(*s)) ++s;
496:
497: *result = '\0';
498: *line = s;
499: }
500:
501: /****************************************************************************/
502:
503: static int matchnum(char **line)
504: {
505: char *s = *line, match = 0;
506: int sign = 1, num = 0;
507:
508: while(isspace(*s)) ++s;
509: if(*s=='\"' || *s=='\'') match = *s++;
510: if(*s=='-') {sign = -1;++s;}
511: if(*s=='+') ++s;
512: while(isspace(*s)) ++s;
513: while(*s>='0' && *s<='9') num = num*10 + (*s++ - '0');
514: if(match && *s==match && s[1]) ++s;
515: while(isspace(*s)) ++s;
516: *line = s;
517: return sign>0?num:-num;
518: }
519:
520: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.