home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / miscutil / pcexecut.lha / PCExecute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-21  |  18.3 KB  |  586 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Peter Vorwerk
  4.  *
  5.  *    Name .....: PCExecute.c
  6.  *    Created ..: Monday 05-Aug-91 11:03
  7.  *    Revision .: 2
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    03-Sep-91       Peter Vorwerk   Added AREXX port
  12.  *    01-Sep-91       Peter Vorwerk   Added Gadgets for F-keys
  13.  *                                    and some other keys
  14.  *
  15.  *    05-Aug-91       Peter Vorwerk   Created this file!
  16.  *
  17.  * $Revision Header ********************************************************/
  18.  #define REVISION 2
  19.  
  20. #define VERSION 1
  21.  
  22. #include <exec/types.h>
  23. #include <intuition/intuition.h>
  24. #include <exec/libraries.h>
  25. #include <janus/janus.h>
  26. #include <libraries/arpbase.h>
  27. #include <libraries/reqbase.h>
  28. #include <proto/req.h>
  29. #include <functions.h>
  30. #include <libraries/rexxhostbase.h>
  31.  
  32. extern char *strupr(char *);
  33.  
  34. UBYTE  *KeyB;
  35. UBYTE  *IntR;
  36.  
  37. struct Syscall86 *Ptr;
  38. RPTR OldPtr;
  39.  
  40. struct Library      *JanusBase;
  41. struct ReqLib       *ReqBase;
  42. struct RexxHostBase *RexxHostBase;
  43. struct RexxHost     *rexx_host;
  44.  
  45. struct Window       *window;
  46. struct GadgetBlock  *first_row;
  47. struct GadgetBlock  *second_row;
  48. struct GadgetBlock  *third_row;
  49.  
  50. UBYTE tab[] = {
  51.     /* 00 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52.     /* 08 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53.     /* 10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54.     /* 18 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55.     /* 20 */    0x39, 0x82, 0xa8, 0x84, 0x85, 0x86, 0x2b, 0x28,
  56.     /* 28 */    0x8a, 0x8b, 0x89, 0x8d, 0x33, 0x0c, 0x34, 0x35,
  57.     /* 30 */    0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  58.     /* 38 */    0x09, 0x0a, 0xa7, 0x27, 0xb3, 0x0d, 0xb4, 0xb5,
  59.     /* 40 */    0x83, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22,
  60.     /* 48 */    0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18,
  61.     /* 50 */    0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11,
  62.     /* 58 */    0x2d, 0x15, 0x2c, 0x1a, 0x2b, 0x1b, 0x87, 0x8c
  63. };
  64.  
  65. UBYTE key[] = {
  66.     /* 00 */    0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
  67.     /* 10 */    0x4b, 0x48, 0x50, 0x4d, 0x47, 0x49, 0x51, 0x4f, 0x01, 0x0f,
  68.     /* 20 */    0x45, 0x46, 0x3a, 0x52, 0x37, 0x1d, 0x2a, 0x38, 0x53, 0x0e,
  69.                 0x39, 0x1c
  70. };
  71.  
  72. void PCKeyB(void)
  73. {
  74.     UBYTE *ptr;
  75.     UWORD *offset;
  76.  
  77. /* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */
  78. /* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse
  79.    genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar.
  80.  
  81.    Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm
  82.    PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts,
  83.    so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die
  84.    nähere Umgebung disassemblieren. */
  85.  
  86. /* Keyboard address. Please note 0x7ffff is NOT the correct address in ALL Systems.
  87.    You must calculate it by contents of (JanusBase + 0x72) + 0x7e000 !! */
  88.  
  89. /* I found this by disassembling the file PCWINDOW. */
  90.  
  91.     KeyB     = (UBYTE *) JanusBase;
  92.     KeyB    += 0x72;
  93.     offset   = (UWORD *) KeyB;
  94.     ptr      = (UBYTE *) GetJanusStart();
  95.     KeyB     = ptr + 0x7e000;
  96.     KeyB    += *offset;
  97.     IntR     = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */
  98. }
  99.  
  100. void PC_Cmd(char *cmd)
  101. {
  102.     UBYTE wert;
  103.  
  104.     if (cmd == NULL || *cmd == 0)
  105.         return;
  106.  
  107.     *KeyB = 0x1d; /* CTRL */
  108.     *IntR = 0xff;
  109.     Delay(1);
  110.     *KeyB = 0x38; /* ALT */
  111.     *IntR = 0xff;
  112.     Delay(1);
  113.     *KeyB = 0x3b; /* F1 */
  114.     *IntR = 0xff;
  115.     Delay(1);
  116.     *KeyB = 0xbb; /* ~F1 */
  117.     *IntR = 0xff;
  118.     Delay(1);
  119.     *KeyB = 0xb8; /* ~ALT */
  120.     *IntR = 0xff;
  121.     Delay(1);
  122.     *KeyB = 0x9d; /* ~CTRL */
  123.     *IntR = 0xff;
  124.     Delay(1);
  125.  
  126.     while(*cmd != '\0')
  127.     {
  128.         wert = tab[*cmd++];
  129.         if (wert > 0x80)
  130.         {
  131.             wert -= 0x80;
  132.  
  133.             *KeyB = (UBYTE) 0x2a;
  134.             *IntR = (UBYTE) 0xff;
  135.             Delay(1);
  136.  
  137.             *KeyB = wert;
  138.             *IntR = (UBYTE) 0xff;
  139.             Delay(1);
  140.  
  141.             *KeyB = (UBYTE) 0xaa;
  142.             *IntR = (UBYTE) 0xff;
  143.             Delay(1);
  144.         }
  145.         else
  146.         {
  147.             *KeyB = wert;
  148.             *IntR = (UBYTE) 0xff;
  149.             Delay(1);
  150.         }
  151.     }
  152.  
  153.     *KeyB = 0x1d; /* CTRL */
  154.     *IntR = 0xff;
  155.     Delay(1);
  156.     *KeyB = 0x38; /* ALT */
  157.     *IntR = 0xff;
  158.     Delay(1);
  159.     *KeyB = 0x3c; /* F2 */
  160.     *IntR = 0xff;
  161.     Delay(1);
  162.     *KeyB = 0xbc; /* ~F2 */
  163.     *IntR = 0xff;
  164.     Delay(1);
  165.     *KeyB = 0xb8; /* ~ALT */
  166.     *IntR = 0xff;
  167.     Delay(1);
  168.     *KeyB = 0x9d; /* ~CTRL */
  169.     *IntR = 0xff;
  170.     Delay(1);
  171. }
  172.  
  173. char text1[10][6] =
  174.         { " F1  ", " F2  ", " F3  ", " F4  ", " F5  ",
  175.           " F6  ", " F7  ", " F8  ", " F9  ", " F10 " };
  176. char text2[10][6] =
  177.         { " <-  ", " up  ", "down ", " ->  ", "Home ",
  178.           "Pg Up", "Pg Dn", " End ", " ESC ", " TAB " };
  179. char text3[10][6] =
  180.         { "NumL ", "ScrL ", "CapsL", " Ins ", "PrtSc",
  181.           "CTRL ", "SHIFT", " ALT ", " Del ", " BS  " };
  182.  
  183. char *cmdlist[] = {
  184. "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
  185.  
  186. "RIGHT", "UP", "DOWN", "LEFT", "HOME", "PAGE_UP", "PAGE_DOWN",
  187. "END", "ESC", "TAB",
  188.  
  189. "NUM_LOCK", "SCROLL_LOCK", "CAPS_LOCK", "INS", "PRINT_SCREEN",
  190. "CTRL", "SHIFT", "ALT", "DEL", "BACKSPACE",
  191.  
  192. "SPACE", "ENTER"
  193. };
  194.  
  195. void Press(char *cmd)
  196. {
  197.     int i,j;
  198.     struct GadgetBlock *gadget;
  199.  
  200.     for(i = 0; i < 32; i++)
  201.     {
  202.         if (Strcmp(cmd,cmdlist[i]) == 0)
  203.         {
  204.             *KeyB = key[i];
  205.             *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  206.             Delay(1);
  207.             if (i > 30)
  208.                 break;
  209.             else if (i > 20)
  210.             {
  211.                 i -= 20;
  212.                 gadget = third_row;
  213.             }
  214.             else if (i >10)
  215.             {
  216.                 i -= 10;
  217.                 gadget = second_row;
  218.             }
  219.             else
  220.                 gadget = first_row;
  221.             while(--i >= 0)
  222.                 gadget++;
  223.             j = RemoveGadget(window,&gadget->Gadget);
  224.             gadget->Gadget.Flags |= SELECTED;
  225.             AddGadget(window,&gadget->Gadget,j);
  226.             RefreshGadgets(&gadget->Gadget,window,NULL);
  227.             break;
  228.         }
  229.     }
  230. }
  231.  
  232. void Release(char *cmd)
  233. {
  234.     int i,j;
  235.     struct GadgetBlock *gadget;
  236.  
  237.     for(i = 0; i < 32; i++)
  238.     {
  239.         if (Strcmp(cmd,cmdlist[i]) == 0)
  240.         {
  241.             *KeyB = key[i] + 0x80;
  242.             *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  243.             Delay(1);
  244.             if (i > 30)
  245.                 break;
  246.             else if (i > 20)
  247.             {
  248.                 i -= 20;
  249.                 gadget = third_row;
  250.             }
  251.             else if (i >10)
  252.             {
  253.                 i -= 10;
  254.                 gadget = second_row;
  255.             }
  256.             else
  257.                 gadget = first_row;
  258.             while(--i >= 0)
  259.                 gadget++;
  260.             j = RemoveGadget(window,&gadget->Gadget);
  261.             gadget->Gadget.Flags &= ~SELECTED;
  262.             AddGadget(window,&gadget->Gadget,j);
  263.             RefreshGadgets(&gadget->Gadget,window,NULL);
  264.             break;
  265.         }
  266.     }
  267. }
  268.  
  269. void GetCmd(char *Buffer)
  270. {
  271.     char                           Undobuffer[256];
  272.     register short                 gadgetnum,class,select;
  273.     register struct  IntuiMessage  *message;
  274.     register int                   i;
  275.  
  276.     struct GadgetBlock             *ok_block;
  277.     struct GadgetBlock             *cancel_block;
  278.     struct StringBlock             *string_block;
  279.  
  280.     struct GadgetBlock             *row;
  281.  
  282.     struct RexxMsg *rexxmessage;   /* incoming rexx messages */
  283.     STRPTR         Arg;            /* Temporary string pointer */
  284.     char           ArgBuff[40];    /* Temporary argument buffer */
  285.     ULONG          SignalSet;      /* Incoming signals. */
  286.     LONG           NumResult;      /* Return code. */
  287.     STRPTR         StringResult;   /* Result string (error message). */
  288.  
  289.     struct NewWindow nw =
  290.         {
  291.             0,0,                                /* LeftEdge, TopEdge */
  292.             640,90,                             /* Width, Height */
  293.             -1,-1,                              /* DetailPen, BlockPen */
  294.             GADGETUP | CLOSEWINDOW,             /* IDCMPFlags */
  295.             SMART_REFRESH | ACTIVATE |
  296.             WINDOWDRAG | WINDOWDEPTH |
  297.             WINDOWCLOSE,                        /* Flags */
  298.             NULL,                               /* FirstGadget */
  299.             NULL,                               /* CheckMark */
  300.             (UBYTE *) "Enter your PC command",  /* Title */
  301.             NULL,                               /* Screen */
  302.             NULL,                               /* BitMap */
  303.             0,0,                                /* MinWidth, MinHeight */
  304.             0,0,                                /* MaxWidth, MaxHeight */
  305.             WBENCHSCREEN                        /* Type (of screen) */
  306.         };
  307.  
  308.     if ((ok_block     = AllocMem(sizeof(struct GadgetBlock),MEMF_CLEAR)) == NULL)
  309.         return;
  310.     if ((cancel_block = AllocMem(sizeof(struct GadgetBlock),MEMF_CLEAR)) == NULL)
  311.         return;
  312.     if ((string_block = AllocMem(sizeof(struct StringBlock),MEMF_CLEAR)) == NULL)
  313.         return;
  314.  
  315.     if ((first_row    = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL)
  316.         return;
  317.     if ((second_row   = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL)
  318.         return;
  319.     if ((third_row    = AllocMem(sizeof(struct GadgetBlock) * 10,MEMF_CLEAR)) == NULL)
  320.         return;
  321.  
  322.     LinkGadget(ok_block,     "Ok",     &nw,  12, 75);
  323.     LinkGadget(cancel_block, "Cancel", &nw, 628, 75);
  324.     LinkStringGadget(string_block, Buffer, Undobuffer, &nw, 616, 255, 12, 60);
  325.     ok_block    ->Gadget.GadgetID  = 1;
  326.     cancel_block->Gadget.GadgetID  = 2;
  327.     string_block->Gadget.GadgetID  = 3;
  328.     cancel_block->Gadget.LeftEdge -= cancel_block->Gadget.Width;
  329.  
  330.     row = first_row;
  331.     for(i = 0; i < 10; i++)
  332.     {
  333.         LinkGadget(row, text1[i], &nw, 12+i*64, 15);
  334.         row->Gadget.Activation |= TOGGLESELECT;
  335.         row->Gadget.GadgetID    = i+4;
  336.         row++;
  337.     }
  338.     row = second_row;
  339.     for(i = 0; i < 10; i++)
  340.     {
  341.         LinkGadget(row, text2[i], &nw, 12+i*64, 30);
  342.         row->Gadget.Activation |= TOGGLESELECT;
  343.         row->Gadget.GadgetID    = i+14;
  344.         row++;
  345.     }
  346.     row = third_row;
  347.     for(i = 0; i < 10; i++)
  348.     {
  349.         LinkGadget(row, text3[i], &nw, 12+i*64, 45);
  350.         row->Gadget.Activation |= TOGGLESELECT;
  351.         if (i == 0 && (Ptr->s86_AX & 0x20))
  352.             row->Gadget.Flags |= SELECTED;
  353.         if (i == 1 && (Ptr->s86_AX & 0x10))
  354.             row->Gadget.Flags |= SELECTED;
  355.         if (i == 2 && (Ptr->s86_AX & 0x40))
  356.             row->Gadget.Flags |= SELECTED;
  357.         if (i == 3 && (Ptr->s86_AX & 0x80))
  358.             row->Gadget.Flags |= SELECTED;
  359.         row->Gadget.GadgetID    = i+24;
  360.         row++;
  361.     }
  362.     Center(&nw, nw.Width - (cancel_block->Gadget.Width >> 1) - 12, 75 + (cancel_block->Gadget.Height >> 1));
  363.  
  364.     if (!(window = (struct Window *) OpenWindow(&nw)))
  365.         return;
  366.  
  367.     ActivateGadget(&string_block->Gadget,window,NULL);
  368.  
  369.     do
  370.     {
  371.         SignalSet = Wait(1L << window->UserPort->mp_SigBit | HOSTMASK(rexx_host));
  372.         if (SignalSet & (1L << window->UserPort->mp_SigBit))
  373.         {
  374.             message   = (struct IntuiMessage *) GetMsg(window->UserPort);
  375.             gadgetnum = ((struct Gadget *) (message->IAddress))->GadgetID;
  376.             select    = ((struct Gadget *) (message->IAddress))->Flags;
  377.             class     = message->Class;
  378.             ReplyMsg((struct Message *)message);
  379.         }
  380.         if (class != CLOSEWINDOW && gadgetnum != 2)
  381.         {
  382.             OldPtr = SetParamOffset(JSERV_PCCALL,JanusMemToOffset(Ptr));
  383.             Ptr->s86_AX  = 0x0200;
  384.             Ptr->s86_INT = 0x16;
  385.             SendJanusInt(JSERV_PCCALL);
  386.             Delay(10);
  387.             SetParamOffset(JSERV_PCCALL,OldPtr);
  388.         }
  389.  
  390.             /* did we get something from rexx? */
  391.  
  392.         if (RexxHostBase)
  393.         {
  394.             while(rexxmessage = GetRexxMsg(rexx_host,FALSE))
  395.             {
  396.                 /* Getting a string pointer means
  397.                  * that we've received a command.
  398.                  */
  399.  
  400.                 StringResult = NULL;
  401.                 NumResult    = 0;
  402.  
  403.                 if(Arg = GetRexxCommand(rexxmessage))
  404.                 {
  405.                     LONG CharCount = 0; /* Need counter, function reentrant. */
  406.  
  407.                     /* Now split the command string into arguments. */
  408.  
  409.                     GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40);
  410.  
  411.                     if (Strcmp(ArgBuff,"COMMAND") == 0)
  412.                     {
  413.                         while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40))
  414.                         {
  415.                             PC_Cmd(strupr(ArgBuff));
  416.                             Delay(1);
  417.                             *KeyB = (UBYTE) 0x39; /* SPACE */
  418.                             *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  419.                             Delay(1);
  420.                         }
  421.                         *KeyB = (UBYTE) 0x1c;     /* ENTER */
  422.                         *IntR = (UBYTE) 0xff;     /* Send Key-Interrupt */
  423.                     }
  424.                     else if (Strcmp(ArgBuff,"KEY") == 0)
  425.                     {
  426.                         char dummy[1024];
  427.  
  428.                         strcpy(dummy,(char *) Arg);
  429.                         while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40))
  430.                             Press((char *) ArgBuff);
  431.  
  432.                         CharCount = 0;
  433.                         GetToken((STRPTR) dummy,&CharCount,(STRPTR) ArgBuff,40);
  434.                         while(GetToken((STRPTR) dummy,&CharCount,(STRPTR) ArgBuff,40))
  435.                             Release((char *) ArgBuff);
  436.                     }
  437.                     else if (Strcmp(ArgBuff,"PRESS") == 0)
  438.                     {
  439.                         while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40))
  440.                             Press((char *) ArgBuff);
  441.                     }
  442.                     else if (Strcmp(ArgBuff,"RELEASE") == 0)
  443.                     {
  444.                         while(GetToken(Arg,&CharCount,(STRPTR) ArgBuff,40))
  445.                             Release((char *) ArgBuff);
  446.                     }
  447.                     else
  448.                     {
  449.                         char dummy[80];
  450.  
  451.                         NumResult = 10;
  452.                         SPrintf(dummy,"ERROR: Command \"%s\" is not supported in this version",
  453.                                     ArgBuff);
  454.                         StringResult = (STRPTR) dummy;
  455.                     }
  456.                 }
  457.                 /* Reply the rexx command. */
  458.                 ReplyRexxCommand(rexxmessage,NumResult,0,StringResult);
  459.             }
  460.         }
  461.  
  462.         if (gadgetnum >= 4 && gadgetnum <= 34)
  463.         {
  464.             if (select & SELECTED)
  465.             {
  466.                 *KeyB = key[gadgetnum-4];
  467.                 *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  468.                 Delay(1);
  469.             }
  470.             else
  471.             {
  472.                 if (gadgetnum != 26)
  473.                     *KeyB = key[gadgetnum-4] + 0x80;
  474.                 else
  475.                     *KeyB = key[gadgetnum-4];
  476.  
  477. /* Caps Lock is a (hardware) switch key. So this key must
  478.    be pressed to send the release code! */
  479.  
  480.                 *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  481.                 Delay(1);
  482.             }
  483.         }
  484.         if (gadgetnum == 1 || gadgetnum == 3)
  485.         {
  486.             int j;
  487.  
  488.             PC_Cmd(strupr(Buffer));
  489.             *KeyB = (UBYTE) 0x1c;     /* ENTER */
  490.             *IntR = (UBYTE) 0xff;     /* Send Key-Interrupt */
  491.             Delay(1);
  492.  
  493.             j = RemoveGadget(window,&string_block->Gadget);
  494.             *Buffer = 0;
  495.             AddGadget(window,&string_block->Gadget,j);
  496.             RefreshGadgets(&string_block->Gadget,window,NULL);
  497.             ActivateGadget(&string_block->Gadget,window,NULL);
  498.         }
  499.     }
  500.     while((gadgetnum != 2) && (class != CLOSEWINDOW));
  501.     CloseWindow(window);
  502.     FreeMem(ok_block,    sizeof(struct GadgetBlock));
  503.     FreeMem(cancel_block,sizeof(struct GadgetBlock));
  504.     FreeMem(string_block,sizeof(struct StringBlock));
  505.  
  506.     FreeMem(first_row,   sizeof(struct GadgetBlock) *10);
  507.     FreeMem(second_row,  sizeof(struct GadgetBlock) *10);
  508.     FreeMem(third_row,   sizeof(struct GadgetBlock) *10);
  509. }
  510.  
  511. void main(int argc, char *argv[])
  512. {
  513.     int i;
  514.     char buf[256] = 0;
  515.  
  516.     if (!(JanusBase   = ArpOpenLibrary("janus.library",0L)))
  517.     {
  518.         Puts("ERROR: Can't find Janus.library");
  519.         exit(10);
  520.     }
  521.     if (!(ReqBase     = (struct ReqLib *) ArpOpenLibrary("req.library",0L)))
  522.     {
  523.         Puts("ERROR: Can't find Req.library");
  524.         exit(10);
  525.     }
  526.     if (!(RexxHostBase = (struct RexxHostBase *) ArpOpenLibrary(REXXHOSTNAME,REXXHOSTMINIMUM)))
  527.     {
  528.         Puts("Sorry, couldn't open rexxhost library.");
  529.     }
  530.     if (RexxHostBase)
  531.     {
  532.         if (!(rexx_host    = CreateRexxHost((STRPTR)"PC_EX")))
  533.         {
  534.             Puts("Sorry, couldn't set up our public rexx port");
  535.         }
  536.     }
  537.     if (RexxHostBase == NULL | rexx_host == NULL)
  538.     {
  539.         Puts("\nSo you can't use the AREXX port.\n");
  540.     }
  541.     if ((Ptr = (struct Syscall86 *) AllocJanusMem(sizeof(struct Syscall86),
  542.         MEMF_PARAMETER | MEM_WORDACCESS)) != NULL)
  543.     {
  544.         OldPtr = SetParamOffset(JSERV_PCCALL,JanusMemToOffset(Ptr));
  545.         Ptr->s86_AX  = 0x0200;
  546.         Ptr->s86_INT = 0x16;
  547.         SendJanusInt(JSERV_PCCALL);
  548.         Delay(10);
  549.         SetParamOffset(JSERV_PCCALL,OldPtr);
  550.     }
  551.     else
  552.     {
  553.         Puts("ERROR: No Janus mem free.");
  554.         if (rexx_host)
  555.             rexx_host = DeleteRexxHost(rexx_host);
  556.         exit(10);
  557.     }
  558.     PCKeyB();
  559.     Printf("%s V%ld.%ld by Peter Vorwerk\tPUBLIC DOMAIN\n",
  560.         BaseName(argv[0]),VERSION,REVISION);
  561.  
  562.     if (argc < 2)
  563.     {
  564.         GetCmd(buf);
  565.         FreeJanusMem(Ptr,sizeof(struct Syscall86));
  566.         if (rexx_host)
  567.             rexx_host = DeleteRexxHost(rexx_host);
  568.         exit(0);
  569.     }
  570.  
  571.     for(i = 1; i < argc; i++)
  572.     {
  573.         PC_Cmd(strupr(argv[i])); /* Only upper case letters and digits are allowed */
  574.         Delay(1);
  575.         *KeyB = (UBYTE) 0x39; /* SPACE */
  576.         *IntR = (UBYTE) 0xff; /* Send Key-Interrupt */
  577.         Delay(1);
  578.     }
  579.     *KeyB = (UBYTE) 0x1c;     /* ENTER */
  580.     *IntR = (UBYTE) 0xff;     /* Send Key-Interrupt */
  581.     FreeJanusMem(Ptr,sizeof(struct Syscall86));
  582.     if (rexx_host)
  583.         rexx_host = DeleteRexxHost(rexx_host);
  584.     exit(0);
  585. }
  586.