Annotation of uae/src/md-amiga/ami-rexx.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.