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