|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * pos-rexx.c ! 5: * ! 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> */ ! 32: #undef DT_DIR ! 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 ! 82: *RexxSysBase; ! 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) { ! 107: fprintf(stderr, "Can't find rexxsyslib.library!\n"); ! 108: return 1; ! 109: } ! 110: if(FindPort(UAE_PORTNAME)) { ! 111: fprintf(stderr, "Port \"%s\" already exists!\n",UAE_PORTNAME); ! 112: return 1; ! 113: } ! 114: ARexxPort = CreatePort(UAE_PORTNAME,0); ! 115: if(!ARexxPort) { ! 116: fprintf(stderr, "Failed to open AREXX port \"%s\"!\n",UAE_PORTNAME); ! 117: return 1; ! 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) { ! 129: struct RexxMsg *msg; ! 130: gui_rexx_s *gui = &gui_rexx[ON_EXIT]; ! 131: ! 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; ! 149: } ! 150: if(RexxSysBase) { ! 151: CloseLibrary((void*)RexxSysBase); ! 152: RexxSysBase = NULL; ! 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)) { ! 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); ! 180: } else { ! 181: sprintf(RESULT,"Drive %d not empty!",drive); ! 182: return RC_WARN; ! 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")) { ! 215: sprintf(RESULT,"%d",framerate); ! 216: return RC_OK; ! 217: } else if(matchstr(&line, "SOUND")) { ! 218: sprintf(RESULT,"%d",sound_available?produce_sound:-1); ! 219: return RC_OK; ! 220: } ! 221: else return RC_ERROR; ! 222: ! 223: if(res) { ! 224: strncpy(RESULT, res, RESULT_LEN); ! 225: if(alc) free(res); ! 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) { ! 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; ! 259: } ! 260: return RC_OK; ! 261: } ! 262: ! 263: /****************************************************************************/ ! 264: ! 265: static int VERSION(char *line) ! 266: { ! 267: if(matchstr(&line,"STRING")) { ! 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); ! 272: } else if(matchstr(&line,"NUM")) { ! 273: sprintf(RESULT,"%d",version); ! 274: } else if(matchstr(&line,"AUTHOR")) { ! 275: sprintf(RESULT,"� by Bernd Schmidt & contributors"); ! 276: } else if(matchstr(&line,"PORT")) { ! 277: sprintf(RESULT,"Amiga Port by Samuel Devulder"); ! 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) { ! 289: framerate = num; ! 290: } else { ! 291: sprintf(RESULT,"Invalid frame rate: %d\n", num); ! 292: return RC_WARN; ! 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) { ! 324: sprintf(RESULT,"Sound not available!"); ! 325: return RC_WARN; ! 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))) { ! 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); ! 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]) { ! 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: } ! 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]) { ! 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: } ! 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, ! 426: *ReplyPort; ! 427: struct RexxMsg *HostMsg, ! 428: *answer; ! 429: int result = RC_WARN; ! 430: ! 431: if(!stricmp(hostname, "COMMAND")) { ! 432: return SystemTagList(cmd,NULL); ! 433: } ! 434: ! 435: if((RexxPort = (void *)FindPort(hostname))) { ! 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!"); ! 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))) { ! 472: while(isspace(*s)) ++s; ! 473: *line = s; ! 474: return 1; ! 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) { ! 490: if(*s == '\\' && (s[1] == '\'' || s[1] == '\"')) ++s; ! 491: if(len > 1) {*result++ = *s;--len;} ! 492: ++s; ! 493: if(!match && isspace(*s)) break; ! 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.