home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / ME494-1.ZIP / COMMOD.SRC < prev    next >
Encoding:
Text File  |  1990-06-05  |  141.7 KB  |  4,441 lines

  1. $MACRO_FILE MECOM;
  2. {******************************************************************************
  3.                                                 MULTI-EDIT MACRO FILE MECOM
  4.  
  5. COM - The communications module main macro.
  6. COM_DATE_TIME - Places the time and date on the MECOM status line.
  7. COM_HELP - Calls the help for the com module.
  8. COM_MAIN_MENU - The top level menu for MECOM.
  9. COM_SETUP_MENU - The MECOM setup menu.
  10. COM_PHONE_MENU - The phone main menu.
  11. COM_OTHER_MENU - The "OTHER" menu.
  12. COM_FILE_MENU - The file download, upload, and log file menu.
  13. COM_SCREEN_MENU - The screen menu
  14. COM_DIR_SHELL - Enter DOS shell from MECOM.
  15. COM_ERROR - Error handling routines for MECOM.
  16. COM_OPEN_PORT - Opens a com port.
  17. COM_FILE - File uploading, downloading and log file.
  18. COM_XFER_BEEP - Beeping for file transfers.
  19. COM_LOG_ERROR - Log file and ASCII upload error routines.
  20. COM_QUIT - Exit prompt for MECOM
  21. COM_ASCII_DOWN - ASCII download
  22. COM_ASCII_UP - ASCII upload
  23. COM_PROTO_MENU - Creates a menu of transfer protocols
  24. COM_SETUP - Installation and setup for MECOM.
  25. COM_SETUP_PORT - A small menu routine for port specific setup.  Used by COM_SETUP.
  26. COM_PHONE - Phone dialing and hang up.
  27. COM_SEND_BREAK - Sends a break condition to the com port.
  28. COM_DUMB - Dumb terminal emulation
  29. COM_ANSI - ANSI terminal emulation
  30. COM_INIT - Gets data from MECOM.DB
  31. COM_WAIT_FOR_STR - Waits for a string or set of strings from the com port.
  32. COM_SEND_STR - Sends a string to the com port.
  33. COM_CONNECT_WAIT - Waits for a connection after dialing.
  34. COM_CURSOR_OFF - Turns the cursor off.
  35. COM_CURSOR_ON - Turns the cursor on.
  36. COM_SCREEN_DUMP - Sends the current screen to a file or printer.
  37. COM_SEND_MSG - Creates a window to edit a message to send to the com port.
  38. COM_VIEW_FILE - Creates a window to view/edit a file.
  39.  
  40.                              (C) Copyright 1990 by American Cybernetics, Inc.
  41. ******************************************************************************}
  42.  
  43. $MACRO COM TRANS;
  44. {*******************************MULTI-EDIT MACRO*******************************
  45.  
  46. Name:    COM
  47.  
  48. Description:    The comunications module main macro.
  49.  
  50.                              (C) Copyright 1990 by American Cybernetics, Inc.
  51. ******************************************************************************}
  52.     def_str(tstr);
  53.     def_int(error, jx, port_num,X1,Y1,X2,Y2,Menu_Choice,Active_Window,Menu_Y,
  54.                     Changes_Made,Duplex,Dest_Bs,Baud,Parity,Data_Bits,Timer_Handle,
  55.                     Stop_Bits,Logging,T_Mode);
  56.     def_char( ch ,Bs_Char);
  57.  
  58.  
  59.     Set_Global_Int('COM_NO_STAT',0);
  60.     Set_Global_Int('Temp_EMS_Stat',EMS_Stat);
  61.     T_Mode := Mode;
  62.     Mode := Term;
  63.     Set_Global_Int('Temp_fkey_row',fkey_row);
  64.     Set_Global_Int('Temp_status_row',status_row);
  65.     Set_Global_Int('Temp_Message_Row',Message_Row);
  66.     Set_Global_Int('MENU_LEVEL',Global_Int('MENU_LEVEL') + 1);
  67.     Set_Global_Int('COM_MENU_LEVEL',Global_Int('MENU_LEVEL'));
  68.     Set_Global_Int('COM_Box_Count',Box_Count);
  69.     status_row := 0;
  70.     fkey_row := 0;
  71.     Message_Row := 0;
  72.     Refresh := False;
  73.     Menu_Y := 2;
  74.     Undo_Stat := False;
  75.  
  76.     Return_Str := '';
  77.     Active_Window := Cur_Window;
  78. {If we've run MECOM before since ME was started.  All these globals should have
  79. values, and therefore it is not neccessary to get them from disk.}
  80.     IF ((Global_Str('COM_ASCII_PARAMS') = '') or
  81.         (Global_Str('COM_LINE_PARAMS') = '') or
  82.         (Global_Str('COM_TERMINAL_PARAMS') = '') or
  83.         (Global_Str('COM_MODEM_PARAMS') = '') or
  84.         (Global_Str('COM_SCREEN_PARAMS') = '') or
  85.         (Global_Str('COM_COLOR_PARAMS') = '') or
  86.         (Global_Str('COM_BOX_PARAMS') = '') or
  87.         (Global_Str('COM_GENERAL_PARAMS') = '')) THEN
  88.         RM('MECOM^COM_INIT');
  89.     END;
  90.  
  91.     IF (Global_Int('COM_DEFAULT_COLORS')) THEN
  92. {If someone used the /B or /C on the command line, default the colors}
  93.         Set_Global_Str('Com_Color_Params','/COLOR=/F=15/B=0');
  94.         Set_Global_Int('COM_DEFAULT_COLORS',0);
  95.     END;
  96.     IF (Global_Int('Com_Port_Open')) THEN
  97.         Call SET_PORT;
  98.     ELSE
  99.         Call INIT_PORT;
  100.     END;
  101.     Call SET_TERM;
  102.     Text_Color_Vp := Parse_Int('/F=',Global_Str('Com_Color_Params')) +
  103.                                     (Parse_Int('/B=',Global_Str('Com_Color_Params')) shl 4);
  104.     IF (Parse_Int('/FS=',Global_Str('Com_Screen_Params')) = True) THEN
  105.         Call FULL_SCREEN;
  106.     ELSE
  107.         Call MAKE_COM_BOX;
  108.     END;
  109.  
  110.     Write_VP('Multi-Edit Communications Module Version 1.10|13|10');
  111.     Set_Global_Int('Com_Cursor_Pos',WhereX_VP or (WhereY_Vp shl $08));
  112.     Set_Global_Int('Com_Logging',False);
  113.     Logging := False;
  114.     Set_Global_Int('Com_ASCII_Download',False);
  115.     Set_Global_Str('Com_Log_Str','');
  116.     Set_Global_Int('Com_First_Log',True);
  117.     Set_Global_Str('Com_Log_File',Parse_Str('/LF=',Global_Str('Com_General_Params')));
  118.     Timer_Handle := set_timer_event('MECOM^COM_DATE_TIME', 18, Term);
  119.  
  120.     IF (Global_Int('Com_Port_Open') = False) THEN
  121.         RM('MECOM^COM_OPEN_PORT /P=0');
  122.     ELSE
  123.         RM('MECOM^COM_OPEN_PORT');
  124.     END;
  125.  
  126.     IF (Global_Int('Com_Port_Open')) THEN
  127.         Port_Num := Global_Int('Com_Port_Num');
  128.     ELSE
  129.         Port_Num := 0;
  130.     END;
  131.  
  132.     Menu_Choice := 1;
  133.  
  134. MAIN_LOOP:
  135.     Call WRITE_STATUS;
  136.     RM('MECOM^COM_' + Parse_Str('/T=',Global_Str('Com_Terminal_Params')));
  137.  
  138.         Jx := Inq_Key(Key1,Key2,TERM,TStr);
  139.         IF (Jx = 1) THEN
  140. MOUSE_MACRO:
  141.             Set_Global_Int('COM_CHANGES_MADE',0);
  142.             Return_Str := '';
  143.             RM(TStr);
  144.             IF (Error_Level) THEN
  145.                 RM('MEERROR');
  146.             END;
  147.             IF (Parse_Int('/QUIT=',Return_Str)) THEN
  148.                 goto exit;
  149.             END;
  150.             IF (Global_Int('COM_CHANGES_MADE') <> 0) THEN
  151.                 IF ((Global_Int('COM_CHANGES_MADE') and $04) <> 0) THEN
  152. {Terminal}
  153.                     Call SET_TERM;
  154.                 END;
  155.                 IF ((Global_Int('COM_CHANGES_MADE') and $08) <> 0) THEN
  156. {Port}
  157.                     Call SET_PORT;
  158.                 END;
  159.                 IF ((Global_Int('COM_CHANGES_MADE') and $10) <> 0) THEN
  160.                     IF (Parse_Int('/FS=',Global_Str('Com_Screen_Params'))) THEN
  161.                         Call FULL_SCREEN;
  162.                     ELSE
  163.                         Kill_Box;
  164.                         Return_Str := '/DRC=1';
  165.                         Goto MAKE_NEW_BOX;
  166.                     END;
  167.                 END;
  168.             END;
  169.             IF (Parse_Int('/BOX=',Return_Str) = -1) THEN
  170. MAKE_NEW_SCREEN:
  171.                 Call FULL_SCREEN;
  172.             END;
  173.             IF (Parse_Int('/BOX=',Return_Str) = 1) THEN
  174. MAKE_NEW_BOX:
  175.                 Jx := Cur_Window;
  176.                 Switch_Window(Active_Window);
  177.                 Fkey_Row := Global_Int('Temp_Fkey_Row');
  178.                 Status_Row := Global_Int('Temp_Status_Row');
  179.                 Message_Row := Global_Int('Temp_Message_Row');
  180.                 Refresh := True;
  181.                 New_Screen;
  182.                 Refresh := False;
  183.                 Switch_Window(Jx);
  184.                 Fkey_Row := 0;
  185.                 Status_Row := 0;
  186.                 Message_Row := 0;
  187.                 Call MAKE_COM_BOX;
  188.             END;
  189.             IF (Parse_Int('/CLS=',Return_Str)) THEN
  190.                 Call CLEAR_SCREEN;
  191.             END;
  192.             Jx := XPos('/WRITE=',Return_Str,1);
  193.             IF (Jx) THEN
  194.             RM('MECOM^COM_' + Parse_Str('/T=',Global_Str('Com_Terminal_Params')) +
  195.                 ' /DO=' + Parse_Str('/WRITE=',Return_Str));
  196.             END;
  197.  
  198. {This is for running a macro after dialing a phone number.}
  199.             Jx := XPos('/PM=',Return_Str,1);
  200.             IF (Jx) THEN
  201.                 RM(Copy(Return_Str,Jx + 4,255));
  202.                 IF (Error_Level) THEN
  203.                     RM('MEERROR');
  204.                 END;
  205.             END;
  206.             Goto MAIN_LOOP;
  207.         ELSE
  208.             IF (Key1 = 0) THEN
  209.                 IF (Key2 = 250) THEN
  210.                     IF (Mou_Last_Y = Global_Int('COM_STATUS_ROW')) THEN
  211. {
  212. These mouse zones are defined for the following status line.  Any mods to the
  213. status line format will require changes to the zone boundries, and the
  214. ASCII UPLOADING message in COM_ASCII_UP.
  215. HELP <F1>   │MENU <F2>   │COM2  2400 8 1 N│LOG CLOSED│ANSI    │01-17-90 03:38pm
  216. }
  217.                         IF ((Mou_Last_X > 0) and (Mou_Last_X < 13)) THEN
  218.                             TStr := 'MECOM^COM_HELP';
  219.                             Goto MOUSE_MACRO;
  220.                         END;
  221.                         IF ((Mou_Last_X > 13) and (Mou_Last_X < 26)) THEN
  222.                             TStr := 'MECOM^COM_MAIN_MENU';
  223.                             Goto MOUSE_MACRO;
  224.                         END;
  225.                         IF ((Mou_Last_X > 26) and (Mou_Last_X < 43)) THEN
  226.                             TStr := 'MECOM^COM_SETUP /TP=4';
  227.                             Goto MOUSE_MACRO;
  228.                         END;
  229.                         IF ((Mou_Last_X > 43) and (Mou_Last_X < 54)) THEN
  230.                             TStr := 'MECOM^COM_FILE /TP=3';
  231.                             Goto MOUSE_MACRO;
  232.                         END;
  233.                         IF ((Mou_Last_X > 54) and (Mou_Last_X < 63)) THEN
  234.                             TStr := 'MECOM^COM_SETUP /TP=3';
  235.                             Goto MOUSE_MACRO;
  236.                         END;
  237.                     ELSIF global_int('COM_MENU_BAR') AND (mou_last_y = (Global_Int('COM_STATUS_ROW') + 1)) AND
  238.                          (mou_last_X < 45) THEN
  239.                         push_key(key1,key2);
  240.                         TStr := 'MECOM^COM_MAIN_MENU';
  241.                         Goto MOUSE_MACRO;
  242.                     END;
  243.                 END;
  244.             END;
  245.         END;
  246.     goto main_loop;
  247.  
  248. {********************************** SUBROUTINES ******************************}
  249. CLEAR_SCREEN:
  250.     Clr_Vp;
  251.     Set_Global_Int('Com_Cursor_Pos',$101);
  252.     RET;
  253.  
  254. MAKE_COM_BOX:
  255.     Kill_Box;
  256.     IF (Parse_Int('/X1=',Global_Str('Com_Box_Params')) < 1) THEN
  257.         Return_Str := '/X1=';
  258.         RM('USERIN^CHNGPARM /G=Com_Box_Params/P=' + '1');
  259.     END;
  260.     IF (Parse_Int('/Y1=',Global_Str('Com_Box_Params')) < 2) THEN
  261.         Return_Str := '/Y1=';
  262.         RM('USERIN^CHNGPARM /G=Com_Box_Params/P=' + '2');
  263.     END;
  264.     IF (Parse_Int('/X2=',Global_Str('Com_Box_Params')) > Screen_Width) THEN
  265.         Return_Str := '/X2=';
  266.         RM('USERIN^CHNGPARM /G=Com_Box_Params/P=' + Str(Screen_Width));
  267.     END;
  268.     IF (Parse_Int('/Y2=',Global_Str('Com_Box_Params')) > (Screen_Length - 1)) THEN
  269.         Return_Str := '/Y2=';
  270.         RM('USERIN^CHNGPARM /G=Com_Box_Params/P=' + Str(Screen_Length));
  271.     END;
  272.     X1 := Parse_Int('/X1=',Global_Str('Com_Box_Params'));
  273.     Y1 := Parse_Int('/Y1=',Global_Str('Com_Box_Params'));
  274.     X2 := Parse_Int('/X2=',Global_Str('Com_Box_Params'));
  275.     Y2 := Parse_Int('/Y2=',Global_Str('Com_Box_Params'));
  276.     Set_Global_Str('Com_Cur_Scrn_Params','/X1=' + Str(X1) + '/Y1=' + Str(Y1) +
  277.                                                                         '/X2=' + Str(X2) + '/Y2=' + Str(Y2));
  278.     Put_Box(X1,Y1,X2,Y2,0,Text_Color_Vp,
  279.                     'MULTI-EDIT COMMUNICATIONS MODULE',False);
  280.  
  281.     Set_Vp(X1 + 1,Y1 + 1,X2 - 1,Y2 - 1);
  282.  
  283.     Call CLEAR_SCREEN;
  284.     Draw_Char(32,1,Global_Int('Temp_status_row'),Stat1_Color,80);
  285.     Draw_Char(32,1,Global_Int('Temp_Fkey_row'),Fnum_Color,80);
  286.     IF (Parse_Int('/SR=',Global_Str('Com_Screen_Params'))) THEN
  287.         Set_Global_Int('COM_STATUS_ROW',Screen_Length);
  288.     ELSE
  289.         Set_Global_Int('COM_STATUS_ROW',1);
  290.     END;
  291.     Set_Global_Int('Com_Full_Screen',False);
  292.     RET;
  293.  
  294. FULL_SCREEN:
  295.     Kill_Box;
  296.     X1 := 0;
  297.   Y1 := (Parse_Int('/SR=',Global_Str('Com_Screen_Params')) = 0) + global_int('COM_MENU_BAR');
  298.     X2 := Screen_Width + 1;
  299.   Y2 := (Screen_Length + 1) - Parse_Int('/SR=',Global_Str('Com_Screen_Params'));
  300.   Set_Global_Str('Com_Cur_Scrn_Params','/X1=' + Str(X1) + '/Y1=' + Str(Y1) +
  301.                                                                         '/X2=' + Str(X2) + '/Y2=' + Str(Y2));
  302.     Set_Vp(X1 + 1,Y1 + 1,X2 - 1,Y2 - 1);
  303.     Draw_Char(32,1,Global_Int('Temp_status_row'),Stat1_Color,80);
  304.     Draw_Char(32,1,Global_Int('Temp_Fkey_row'),Fnum_Color,80);
  305.     IF (Parse_Int('/SR=',Global_Str('Com_Screen_Params'))) THEN
  306.         Set_Global_Int('COM_STATUS_ROW',Screen_Length);
  307.     ELSE
  308.         Set_Global_Int('COM_STATUS_ROW',1);
  309.     END;
  310.  
  311.     Call CLEAR_SCREEN;
  312.     Set_Global_Int('Com_Full_Screen',True);
  313.     RET;
  314.  
  315. SET_TERM:
  316.     Duplex := Parse_Int('/D=',Global_Str('Com_Terminal_Params'));
  317.     Vp_Bs := Parse_Int('/BT=',Global_Str('Com_Terminal_Params'));
  318.     Vp_Wrap := Parse_Int('/W=',Global_Str('Com_Terminal_Params'));
  319.     Vp_Lf := Parse_Int('/CI=',Global_Str('Com_Terminal_Params'));
  320.     Bs_Char := Char(Parse_Int('/BK=',Global_Str('Com_Terminal_Params')));
  321.     RET;
  322.  
  323. SET_PORT:
  324.     Baud := Parse_Int('/B=',Global_Str('Com_Cur_Line_Params'));
  325.     Parity := Parse_Int('/P=',Global_Str('Com_Cur_Line_Params'));
  326.     Data_Bits := Parse_Int('/D=',Global_Str('Com_Cur_Line_Params'));
  327.     Stop_Bits := Parse_Int('/S=',Global_Str('Com_Cur_Line_Params'));
  328.     RET;
  329.  
  330. INIT_PORT:
  331.     Set_Global_Int('Com_Port_Num',Parse_Int('/C=',Global_Str('Com_Line_Params')));
  332.     Baud := Parse_Int('/B=',Global_Str('Com_Line_Params'));
  333.     Parity := Parse_Int('/P=',Global_Str('Com_Line_Params'));
  334.     Data_Bits := Parse_Int('/D=',Global_Str('Com_Line_Params'));
  335.     Stop_Bits := Parse_Int('/S=',Global_Str('Com_Line_Params'));
  336.     Set_Global_Str('Com_Cur_Line_Params',
  337.         '/C=' + Str(Global_Int('Com_Port_Num')) +
  338.         '/B=' + Str(Baud) +
  339.         '/P=' + Str(Parity) +
  340.         '/D=' + Str(Data_Bits) +
  341.         '/S=' + Str(Stop_Bits)
  342.     );
  343.     RET;
  344.  
  345.  
  346.     def_int( stat_row );
  347. WRITE_STATUS:
  348. {If any mods are made to the format of the status line, you must follow through
  349. with mods to the mouse zones and to the position that the date and time gets
  350. written in COM_DATE_TIME.
  351. Also, the ASCII UPLOADING message in COM_ASCII_UP.
  352. }
  353.     stat_row := Global_Int('COM_STATUS_ROW');
  354.     TStr :=     'HELP ' + Copy(Global_Str('!COM_HELP') + '        ',1,7) + '│MENU ' +
  355.                         Copy(Global_Str('!COM_MENU') + '        ',1,7) + '│COM' +
  356.                                     Str(Global_Int('Com_Port_Num')) + ' ';
  357.     IF (Global_Int('Com_Port_Open')) THEN
  358.         TStr := TStr +
  359.             Copy('  110  300  450  600 1200 2400 4800 960019200',
  360.             (Baud * 5) + 1,5) + ' ' +
  361.             Str(Data_Bits + 5) + ' ' +
  362.             Str(Stop_Bits + 1) + ' ' +
  363.             Copy('NOE', Parity + 1,1);
  364.     ELSE
  365.         TStr := TStr + 'CLOSED     ';
  366.     END;
  367.     TStr := TStr + '│LOG ' + Copy('CLOSEDOPEN  ',
  368.         (Global_Int('Com_Logging') * 6) + 1,6) + '│' +
  369.         Copy(Parse_Str('/T=',Global_Str('Com_Terminal_Params')) + '        ',1,8) +
  370.         '│' + Date + ' ' + STR_DEL(TIME,6,3) + ' ';
  371.  
  372.  
  373.     WRITE(TStr,1,stat_row,0,Stat2_Color);
  374.     IF (Global_Int('Com_ASCII_Download')) THEN
  375.         WRITE(' ASCII DOWNLOADING ',43,Global_Int('COM_STATUS_ROW'),0,Working_Color);
  376.     END;
  377.  
  378.     IF global_int('COM_MENU_BAR') THEN
  379.         ++stat_Row;
  380.         Draw_Char(32, 1, stat_row, m_t_color, screen_width );
  381.         Write('File Phone Setup Display Message-editor Quit', 1, stat_row, 0, m_t_color );
  382.         Draw_Char( 70, 1, stat_row, m_s_color, 1 );
  383.         Draw_Char( 80, 6, stat_row, m_s_color, 1 );
  384.         Draw_Char( 83, 12, stat_row, m_s_color,1  );
  385.         Draw_Char( 68, 18, stat_row, m_s_color,1  );
  386.         Draw_Char( 77, 26, stat_row, m_s_color,1 );
  387.         Draw_Char( 81, 41, stat_row, m_s_color,1 );
  388.         --stat_row;
  389.     END;
  390.     RET;
  391.  
  392. {*****************************************************************************}
  393.  
  394. error_exit:
  395.  
  396. exit:
  397. {This kills the box from the QUIT menu}
  398.     Kill_Box;
  399.  
  400.     IF (Global_Int('Com_Full_Screen') = False) THEN
  401.         Kill_Box;
  402.     END;
  403.     Set_Vp(1,1,Screen_Width,Screen_Length);
  404.     IF (Global_Int('Com_Logging')) THEN
  405.         Return_Int := Length(Global_Str('Com_Log_Str'));
  406.         Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Jx);
  407.         IF (Return_Int > Jx) THEN
  408.             Return_Int := 241;
  409.             RM('COM_LOG_ERROR');
  410.         END;
  411.         IF (Error) THEN
  412.             Return_Int := Error;
  413.             RM('COM_LOG_ERROR');
  414.         END;
  415.         Error := S_Close_File(Global_Int('Com_Log_Handle'));
  416.         IF (Error) THEN
  417.             Return_Int := Error;
  418.             RM('COM_LOG_ERROR');
  419.         END;
  420.         Set_Global_Int('Com_Logging',False);
  421.     END;
  422.     IF (Global_Int('Com_ASCII_Download')) THEN
  423.         Return_Int := Length(Global_Str('Com_Log_Str'));
  424.         Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Jx);
  425.         IF (Return_Int > Jx) THEN
  426.             Return_Int := 241;
  427.             RM('COM_LOG_ERROR /A=1');
  428.         END;
  429.         IF (Error) THEN
  430.             Return_Int := Error;
  431.             RM('COM_LOG_ERROR /A=1');
  432.         END;
  433.         Error := S_Close_File(Global_Int('Com_ASCII_Handle'));
  434.         IF (Error) THEN
  435.             Return_Int := Error;
  436.             RM('COM_LOG_ERROR /A=1');
  437.         END;
  438.         Set_Global_Int('Com_ASCII_Download',False);
  439.     END;
  440.     Set_Global_Str('Com_Log_Str','');
  441.     Switch_Window(Active_Window);
  442. {dump all non-transient macros}
  443.  
  444. UNLOAD_MACRO('COM_DUMB');
  445. UNLOAD_MACRO('COM_ANSI');
  446.  
  447.     Refresh := True;
  448.     status_row := Global_Int('Temp_status_row');
  449.     fkey_row := Global_Int('Temp_fkey_row');
  450.     Message_Row := Global_Int('Temp_Message_Row');
  451. {The new timer event system}
  452.     kill_timer_event(Timer_Handle);
  453.     Mode := T_Mode;
  454.  
  455. {Get rid of most com related globals}
  456.     Set_Global_Int('COM_FULL_SCREEN',0);
  457.     Set_Global_Int('COM_FIRST_LOG',0);
  458.     Set_Global_Int('TEMP_MESSAGE_ROW',0);
  459.     Set_Global_Int('TEMP_STATUS_ROW',0);
  460.     Set_Global_Int('TEMP_FKEY_ROW',0);
  461.     Set_Global_Int('TEMP_EMS_STAT',0);
  462.     Set_Global_Str('Com_Cur_Scrn_Params','');
  463.     Set_Global_Str('COM_LOG_FILE','');
  464.     Set_Global_Int('COM_MENU_LEVEL',0);
  465.     new_screen;
  466.     Undo_Stat := True;
  467.     Set_Global_Int('MENU_LEVEL',Global_Int('MENU_LEVEL') - 1);
  468. {
  469.     IF (Box_Count <> Global_Int('COM_Box_Count')) THEN
  470. Beep;
  471. Make_Message('Box_Count=' + Str(Box_Count) + ' COM_Box_Count=' + Str(Global_Int('COM_Box_Count')));
  472. Read_Key;
  473.     END;
  474. }
  475. END_MACRO;
  476.  
  477. $MACRO COM_DATE_TIME;
  478. {*******************************MULTI-EDIT MACRO*******************************
  479.  
  480. Name:    COM_DATE_TIME
  481.  
  482. Description:    Updates the date and time on the MECOM staus line.  Intended to
  483.                             be run via the timer event system.
  484.  
  485.                              (C) Copyright 1990 by American Cybernetics, Inc.
  486. ******************************************************************************}
  487. {
  488. WRITE('Box_Count=' + Str(Box_Count) + ' COM_Box_Count=' + Str(Global_Int('COM_Box_Count')) +  '            ',1,Global_Int('COM_STATUS_ROW'),0,Stat2_Color);
  489. }
  490.     IF ((Global_Int('COM_NO_STAT') = 0) and
  491.         (Global_Int('MENU_LEVEL') <= Global_Int('COM_MENU_LEVEL'))) THEN
  492.         WRITE(Date + ' ' + STR_DEL(TIME,6,3),64,Global_Int('COM_STATUS_ROW'),0,Stat2_Color);
  493.     END;
  494. END_MACRO;
  495.  
  496. $MACRO COM_HELP TRANS;
  497. {*******************************MULTI-EDIT MACRO*******************************
  498.  
  499. Name:    COM_HELP
  500.  
  501. Description:    The comunications help.
  502.  
  503.                              (C) Copyright 1990 by American Cybernetics, Inc.
  504. ******************************************************************************}
  505.     Def_Int(T_No_Stat);
  506.     T_No_Stat := Global_Int('COM_NO_STAT');
  507.     Set_Global_Int('COM_NO_STAT',True);
  508.     Help('MECOM^QR');
  509.     Set_Global_Int('COM_NO_STAT',T_No_Stat);
  510. END_MACRO;
  511.  
  512. $MACRO COM_MAIN_MENU;
  513. {*******************************MULTI-EDIT MACRO*******************************
  514.  
  515. Name:    COM_MAIN_MENU
  516.  
  517. Description:    The comunications module top level menu.
  518.  
  519.                              (C) Copyright 1990 by American Cybernetics, Inc.
  520. ******************************************************************************}
  521.  
  522.     Create_Global_Str('COMSTR_1','/H=MECOM^FIL/M=MECOM^COM_FILE_MENU');
  523.     Create_Global_Str('XCOMSTR_1','File');
  524.     Create_Global_Str('COMSTR_2','/H=MECOM^PHON/M=MECOM^COM_PHONE_MENU');
  525.     Create_Global_Str('XCOMSTR_2','Phone');
  526.     Create_Global_Str('COMSTR_3','/H=MECOM^SET/M=MECOM^COM_SETUP_MENU');
  527.     Create_Global_Str('XCOMSTR_3','Setup');
  528.     Create_Global_Str('COMSTR_4','/H=MECOM^SCR/M=MECOM^COM_SCREEN_MENU');
  529.     Create_Global_Str('XCOMSTR_4','Display');
  530.     Create_Global_Str('COMSTR_5','/H=MECOM^ME/S=2/M=MECOM^COM_SEND_MSG');
  531.     Create_Global_Str('XCOMSTR_5','Message-editor');
  532.     Create_Global_Str('COMSTR_6','/H=MECOM^QUI/M=MECOM^COM_QUIT');
  533.     Create_Global_Str('XCOMSTR_6','Quit');
  534.  
  535.     RM('USERIN^TOPMENU /M=XCOMSTR_/G=COMSTR_/#=6/X=1/S=1/L=COMMUNICATIONS MAIN MENU/Y=2/GCLR=1/B=' + str(global_int('COM_MENU_BAR')));
  536.  
  537. END_MACRO;
  538.  
  539. $MACRO COM_SETUP_MENU;
  540. {*******************************MULTI-EDIT MACRO*******************************
  541.  
  542. Name:    COM_SETUP_MENU
  543.  
  544. Description:    The comunications module installation and setup menu.
  545.  
  546. Parameters:
  547.                             /X=    The upper left corner X coordinate of the menu box.
  548.                             /Y=    The upper left corner Y coordinate of the menu box.
  549.                             /BK= Kill box when done, used when calling from a keystroke.
  550.  
  551.                              (C) Copyright 1990 by American Cybernetics, Inc.
  552. ******************************************************************************}
  553.  
  554.     Set_Global_Int('COM_CHANGES_MADE',0);
  555.     Create_Global_Str('COMSETSTR_1','/H=MECOM^SETGEN/M=MECOM^COM_SETUP /TP=1');
  556.     Create_Global_Str('XCOMSETSTR_1','General(file names, etc.)...          ^' + global_str('!COM_SM_KEY1'));
  557.     Create_Global_Str('COMSETSTR_2','/H=MECOM^SETMOD/M=MECOM^COM_SETUP /TP=2');
  558.     Create_Global_Str('XCOMSETSTR_2','Modem...                              ^' + global_str('!COM_SM_KEY2'));
  559.     Create_Global_Str('COMSETSTR_3','/H=MECOM^SETTER/M=MECOM^COM_SETUP /TP=3');
  560.     Create_Global_Str('XCOMSETSTR_3','Terminal...                           ^' + global_str('!COM_SM_KEY3'));
  561.     Create_Global_Str('COMSETSTR_4','/H=MECOM^SETPOR/M=MECOM^COM_SETUP /TP=4');
  562.     Create_Global_Str('XCOMSETSTR_4','com Port settings(baud rate, etc.)... ^' + global_str('!COM_SM_KEY4'));
  563.     Create_Global_Str('COMSETSTR_5','/H=MECOM^SETSCR/M=MECOM^COM_SETUP /TP=5');
  564.     Create_Global_Str('XCOMSETSTR_5','Screen...                             ^' + global_str('!COM_SM_KEY5'));
  565.     Create_Global_Str('COMSETSTR_6','');
  566.     Create_Global_Str('XCOMSETSTR_6','|254');
  567.     Create_Global_Str('COMSETSTR_7','/H=MECOM^SETDNL/M=MECOM^COM_SETUP /TP=6');
  568.     Create_Global_Str('XCOMSETSTR_7','Download Protocols...                 ^' + global_str('!COM_SM_KEY7'));
  569.     Create_Global_Str('COMSETSTR_8','/H=MECOM^SETUPL/M=MECOM^COM_SETUP /TP=7');
  570.     Create_Global_Str('XCOMSETSTR_8','Upload Protocols...                   ^' + global_str('!COM_SM_KEY8'));
  571.     Create_Global_Str('COMSETSTR_9','/H=MECOM^SETASC/M=MECOM^COM_SETUP /TP=8');
  572.     Create_Global_Str('XCOMSETSTR_9','asCii transfer...                     ^' + global_str('!COM_SM_KEY9'));
  573.     Create_Global_Str('COMSETSTR_10','');
  574.     Create_Global_Str('XCOMSETSTR_10','|254');
  575.     Create_Global_Str('COMSETSTR_11','/H=MECOM^SETSAV/S=2/M=MECOM^COM_SETUP /TP=10');
  576.     Create_Global_Str('XCOMSETSTR_11','saVe setup                           ^' + global_str('!COM_SM_KEY11'));
  577.  
  578.     RM('USERIN^SUBMENU /M=XCOMSETSTR_/G=COMSETSTR_/#=11/S=1/L=SETUP/BC=1/GCLR=1/X='
  579.         + Parse_Str('/X=',MParm_Str) + '       /Y=' + Parse_Str('/Y=',MParm_Str));
  580.  
  581.     IF ((Parse_Int('/BK=',MParm_Str) = True) and (Return_Int = 9)) THEN
  582.         Kill_Box;
  583.     END;
  584. END_MACRO;
  585.  
  586. $MACRO COM_PHONE_MENU;
  587. {*******************************MULTI-EDIT MACRO*******************************
  588.  
  589. Name:    COM_PHONE_MENU
  590.  
  591. Description:    The comunications module menu for dialing, etc.
  592.  
  593. Parameters:
  594.                             /X=    The upper left corner X coordinate of the menu box.
  595.                             /Y=    The upper left corner Y coordinate of the menu box.
  596.  
  597.                              (C) Copyright 1990 by American Cybernetics, Inc.
  598. ******************************************************************************}
  599.  
  600.     Create_Global_Str('COMPHONESTR_1','/H=MECOM^PHONAUT/M=MECOM^COM_PHONE /TP=1');
  601.     Create_Global_Str('XCOMPHONESTR_1','autoDial directory...     ^' + global_str('!COM_PM_KEY1'));
  602.     Create_Global_Str('COMPHONESTR_2','/H=MECOM^PHONMAN/M=MECOM^COM_PHONE /TP=2');
  603.     Create_Global_Str('XCOMPHONESTR_2','Manual dialing...         ^' + global_str('!COM_PM_KEY2'));
  604.     Create_Global_Str('COMPHONESTR_3','/H=MECOM^PHONRED/S=2/M=MECOM^COM_PHONE /TP=4');
  605.     Create_Global_Str('XCOMPHONESTR_3','Redial last dialed number ^' + global_str('!COM_PM_KEY3'));
  606.     Create_Global_Str('COMPHONESTR_4','');
  607.     Create_Global_Str('XCOMPHONESTR_4','|254');
  608.     Create_Global_Str('COMPHONESTR_5','/H=MECOM^PHONHAN/S=2/M=MECOM^COM_PHONE /TP=3');
  609.     Create_Global_Str('XCOMPHONESTR_5','Hang up                   ^' + global_str('!COM_PM_KEY5'));
  610.     Create_Global_Str('COMPHONESTR_6','/H=MECOM^BREAK/S=2/M=MECOM^COM_SEND_BREAK');
  611.     Create_Global_Str('XCOMPHONESTR_6','send a Break              ^' + global_str('!COM_PM_KEY6'));
  612.  
  613.     RM('USERIN^SUBMENU /M=XCOMPHONESTR_/G=COMPHONESTR_/#=6/S=1/BC=1/L=PHONE/X='
  614.         + Parse_Str('/X=',MParm_Str) + '/GCLR=1/Y=' + Parse_Str('/Y=',MParm_Str));
  615.  
  616. END_MACRO;
  617.  
  618. $MACRO COM_FILE_MENU;
  619. {*******************************MULTI-EDIT MACRO*******************************
  620.  
  621. Name:    COM_FILE_MENU
  622.  
  623. Description:    The comunications module menu for file functions.
  624.  
  625. Parameters:
  626.                             /X=    The upper left corner X coordinate of the menu box.
  627.                             /Y=    The upper left corner Y coordinate of the menu box.
  628.  
  629.                              (C) Copyright 1990 by American Cybernetics, Inc.
  630. ******************************************************************************}
  631.     Def_Int(log,choices);
  632.     Log := Global_Int('Com_Logging') = True;
  633.  
  634.     Create_Global_Str('COMFILESTR_1','/H=MECOM^FILDOW/S=2/M=MECOM^COM_FILE /TP=1/KB=1');
  635.     Create_Global_Str('XCOMFILESTR_1','Download...       ^' + global_str('!COM_FM_KEY1'));
  636.     Create_Global_Str('COMFILESTR_2','/H=MECOM^FILUPL/S=2/M=MECOM^COM_FILE /TP=2/KB=1');
  637.     Create_Global_Str('XCOMFILESTR_2','Upload...         ^' + global_str('!COM_FM_KEY2'));
  638.     Create_Global_Str('COMFILESTR_3','');
  639.     Create_Global_Str('XCOMFILESTR_3','|254');
  640.     Create_Global_Str('COMFILESTR_4','/H=MECOM^FILLOG/M=MECOM^COM_FILE /TP=3/S=' + Str(Log * 2));
  641.     Create_Global_Str('XCOMFILESTR_4',Copy(Copy('closeopen',(not(Log) * 5) + 1,5) + ' Log file...  ',1,18) + '^' + global_str('!COM_FM_KEY4'));
  642.     IF (Log) THEN
  643.         Create_Global_Str('COMFILESTR_5','/H=MECOM^FILVIE/M=MECOM^COM_VIEW_FILE /LOG=1');
  644.         Create_Global_Str('XCOMFILESTR_5','view/Edit log     ^' + global_str('!COM_FM_KEY5'));
  645.         Choices := 6;
  646.     ELSE
  647.         Choices := 5;
  648.     END;
  649.     Create_Global_Str('COMFILESTR_' + Str(Choices),'/H=MECOM^FILVIE/M=MECOM^COM_VIEW_FILE');
  650.     Create_Global_Str('XCOMFILESTR_' + Str(Choices),'View/edit file... ^' + global_str('!COM_FM_KEY6'));
  651.     ++Choices;
  652.     Create_Global_Str('COMFILESTR_' + Str(Choices),'');
  653.     Create_Global_Str('XCOMFILESTR_' + Str(Choices),'|254');
  654.     ++Choices;
  655.     Create_Global_Str('COMFILESTR_' + Str(Choices),'/H=MECOM^DOS/S=1/M=MECOM^COM_DIR_SHELL');
  656.     Create_Global_Str('XCOMFILESTR_' + Str(Choices),'dos Shell         ^' + global_str('!COM_FM_KEY8'));
  657.     ++Choices;
  658.     Create_Global_Str('COMFILESTR_' + Str(Choices),'/H=MECOM^QUI/M=MECOM^COM_QUIT');
  659.     Create_Global_Str('XCOMFILESTR_' + Str(Choices),'Exit...           ^' + global_str('!COM_FM_KEY9'));
  660.  
  661.     RM('USERIN^SUBMENU /M=XCOMFILESTR_/G=COMFILESTR_/#=' + Str(Choices) + '/S=1/BC=1/L=FILE/X='
  662.         + Parse_Str('/X=',MParm_Str) + '/GCLR=1/Y=' + Parse_Str('/Y=',MParm_Str));
  663.  
  664. END_MACRO;
  665.  
  666. $MACRO COM_SCREEN_MENU;
  667. {*******************************MULTI-EDIT MACRO*******************************
  668.  
  669. Name:    COM_SCREEN_MENU
  670.  
  671. Description:    The comunications module menu for screen functions.
  672.  
  673. Parameters:
  674.                             /X=    The upper left corner X coordinate of the menu box.
  675.                             /Y=    The upper left corner Y coordinate of the menu box.
  676.                             /C=    Clear screen.  Don't invoke menu.
  677. Returns:
  678.                             Return_Str contains special parameters interpreted by the
  679.                             communications main macro to invoke certain actions.
  680.  
  681.                              (C) Copyright 1990 by American Cybernetics, Inc.
  682. ******************************************************************************}
  683.  
  684.     IF (Parse_Int('/C=',MParm_Str)) THEN
  685.         Goto CLEAR_SCREEN;
  686.     END;
  687.  
  688.     Def_Int(X1,Y1,X2,Y2);
  689.     Create_Global_Str('COMSCRSTR_1','/H=MECOM^SCRBOX');
  690.     Create_Global_Str('XCOMSCRSTR_1','Box           ^' + global_str('!COM_DM_KEY1'));
  691.     Create_Global_Str('COMSCRSTR_2','/H=MECOM^SCRFUL');
  692.     Create_Global_Str('XCOMSCRSTR_2','Full screen   ^' + global_str('!COM_DM_KEY2'));
  693.     Create_Global_Str('COMSCRSTR_3','');
  694.     Create_Global_Str('XCOMSCRSTR_3','|254');
  695.     Create_Global_Str('COMSCRSTR_4','/H=MECOM^SCRCLE');
  696.     Create_Global_Str('XCOMSCRSTR_4','Clear          ^' + global_str('!COM_DM_KEY4'));
  697.     Create_Global_Str('COMSCRSTR_5','/H=MECOM^DUMP/S=2/M=MECOM^COM_SCREEN_DUMP');
  698.     Create_Global_Str('XCOMSCRSTR_5','Screen dump... ^' + global_str('!COM_DM_KEY5'));
  699.  
  700.     RM('USERIN^SUBMENU /M=XCOMSCRSTR_/G=COMSCRSTR_/#=5/S=1/BC=1/L=DISPLAY/X='
  701.         + Parse_Str('/X=',MParm_Str) + '/GCLR=1/Y=' + Parse_Str('/Y=',MParm_Str));
  702.  
  703.     IF ((Return_Int = 2) and
  704.         (Global_Int('Com_Full_Screen') = False)) THEN
  705.         Return_Str := '/CLS=1/BOX=-1';
  706.     END;
  707.     IF ((Return_Int = 1)  and
  708.         (Global_Int('Com_Full_Screen') = True)) THEN
  709.         Return_Str := '/CLS=1/BOX=1';
  710.     END;
  711.     IF (Return_Int = 3) THEN
  712. CLEAR_SCREEN:
  713.         Text_Color_Vp := Parse_Int('/F=',Global_Str('Com_Color_Params')) or
  714.                                         (Parse_Int('/B=',Global_Str('Com_Color_Params')) shl 4);
  715.  
  716.         IF (Parse_Int('/C=',MParm_Str) = 0) THEN
  717.             Kill_Box;
  718.             Kill_Box;
  719.         END;
  720.         Return_Str := '/CLS=1';
  721.     END;
  722.  
  723. END_MACRO;
  724.  
  725. $MACRO COM_DIR_SHELL TRANS;
  726. {*******************************MULTI-EDIT MACRO*******************************
  727.  
  728. Name:    COM_DIR_SHELL
  729.  
  730. Description:    The comunications module call to the DOS shell.
  731.  
  732.                              (C) Copyright 1990 by American Cybernetics, Inc.
  733. ******************************************************************************}
  734.     Refresh := true;
  735.     fkey_row := Global_Int('Temp_fkey_row');
  736. {
  737.     Message_Row := Global_Int('Temp_Message_Row');
  738. }
  739. {run DIRSHELL as normal except disallow file loading}
  740.     RM('DIRSHELL /S=1');
  741.     fkey_row := 0;
  742. {
  743.     Message_Row := 0;
  744. }
  745.     Set_Vp(Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params')) + 1,
  746.         Parse_Int('/Y1=',Global_Str('Com_Cur_Scrn_Params')) + 1,
  747.         Parse_Int('/X2=',Global_Str('Com_Cur_Scrn_Params')) - 1,
  748.         Parse_Int('/Y2=',Global_Str('Com_Cur_Scrn_Params')) - 1);
  749.     Text_Color_Vp := Parse_Int('/F=',Global_Str('Com_Color_Params')) +
  750.                                     (Parse_Int('/B=',Global_Str('Com_Color_Params')) shl 4);
  751.     refresh := false;
  752. END_MACRO;
  753.  
  754. $MACRO COM_ERROR TRANS;
  755. {*******************************MULTI-EDIT MACRO*******************************
  756.  
  757. Name:    COM_ERROR
  758.  
  759. Description:    The comunications module error message handler.
  760.  
  761. Parameters:
  762.                             Return_Int - the error code.
  763.  
  764. Returns:
  765.                             Return_Str contains the error message.
  766.  
  767.                              (C) Copyright 1990 by American Cybernetics, Inc.
  768. ******************************************************************************}
  769.  
  770.     Return_Str := '#' + Str(Return_Int);
  771.  
  772.     IF (Return_Int = 2) THEN
  773.         Return_Str := 'Invalid COM port number';
  774.     END;
  775.     IF (Return_Int = 3) THEN
  776.         Return_Str := 'COM port not open';
  777.     END;
  778.     IF (Return_Int = 6) THEN
  779.         Return_Str := 'No serial port found';
  780.     END;
  781.     IF (Return_Int = 7) THEN
  782.         Return_Str := 'Output queue full';
  783.     END;
  784.     IF (Return_Int = 9) THEN
  785.         Return_Str := 'Com port already open';
  786.     END;
  787.     IF (Return_Int = 10) THEN
  788.         Return_Str := 'Input queue is empty';
  789.     END;
  790.     IF (Return_Int = 52) THEN
  791.         Return_Str := 'Invalid XMODEM parameter';
  792.     END;
  793.     IF (Return_Int = 53) THEN
  794.         Return_Str := 'Unexpected control character';
  795.     END;
  796.     IF (Return_Int = 54) THEN
  797.         Return_Str := 'Wrong packet number received';
  798.     END;
  799.     IF (Return_Int = 60) THEN
  800.         Return_Str := 'No startup SOH received';
  801.     END;
  802.     IF (Return_Int = 61) THEN
  803.         Return_Str := 'Incomplete packet received';
  804.     END;
  805.     IF (Return_Int = 62) THEN
  806.         Return_Str := 'Overrun error or break received';
  807.     END;
  808.     IF (Return_Int = 63) THEN
  809.         Return_Str := 'Checksum or CRC failed';
  810.     END;
  811.     IF (Return_Int = 64) THEN
  812.         Return_Str := 'Remote aborted transfer';
  813.     END;
  814.     IF (Return_Int = 65) THEN
  815.         Return_Str := 'Local aborted transfer';
  816.     END;
  817.     IF (Return_Int = 70) THEN
  818.         Return_Str := 'Cannot open file';
  819.     END;
  820.     IF (Return_Int = 71) THEN
  821.         Return_Str := 'Error writing to file';
  822.     END;
  823.     IF (Return_Int = 72) THEN
  824.         Return_Str := 'Cannot close file';
  825.     END;
  826.     IF (Return_Int = 80) THEN
  827.         Return_Str := 'No startup signal received';
  828.     END;
  829.     IF (Return_Int = 81) THEN
  830.         Return_Str := 'Wrong startup character received';
  831.     END;
  832.     IF (Return_Int = 82) THEN
  833.         Return_Str := 'Packet acknowledgement failure';
  834.     END;
  835.     IF (Return_Int = 83) THEN
  836.         Return_Str := 'Receiver rejected last packet';
  837.     END;
  838.     IF (Return_Int = 84) THEN
  839.         Return_Str := 'Final ACK not received';
  840.     END;
  841.     IF (Return_Int = 85) THEN
  842.         Return_Str := 'Time out waiting for final ACK';
  843.     END;
  844.     IF (Return_Int = 86) THEN
  845.         Return_Str := 'Unable to drain input or output queue';
  846.     END;
  847.     IF (Return_Int = 90) THEN
  848.         Return_Str := 'Cannot open file';
  849.     END;
  850.     IF (Return_Int = 91) THEN
  851.         Return_Str := 'Error reading file';
  852.     END;
  853.     IF (Return_Int = 92) THEN
  854.         Return_Str := 'Cannot close file';
  855.     END;
  856.     IF (Return_Int = 200) THEN
  857.         Return_Str := 'Not true YMODEM-Batch, try XMODEM-1K';
  858.     END;
  859. END_MACRO;
  860.  
  861. $MACRO COM_OPEN_PORT;
  862. {*******************************MULTI-EDIT MACRO*******************************
  863.  
  864. Name:    COM_OPEN_PORT
  865.  
  866. Description:    The comunications module macro to open and initialize a com port.
  867.  
  868. Parameters:
  869.                             /P=  the port that is currently open.  If no port is open, or you
  870.                             don't want the currently open port to be closed, set this to 0.
  871.  
  872. NOTE:  All other parameters are derived from Global_Str('COM_LINE_PARAMS').
  873.  
  874. Returns:
  875.                             If successful, it will set the following global variables:
  876.                                 Global_Int('Com_Port_Num')   =   /C=
  877.                                 Global_Int('Com_Port_Open')  =   True
  878.                             If unsuccessful, it will set:
  879.                                 Global_Int('Com_Port_Open')  =   False
  880.  
  881.                              (C) Copyright 1990 by American Cybernetics, Inc.
  882. ******************************************************************************}
  883.  
  884.     Def_Int(Port_Num,Error,Jx,Already_Open);
  885.     Def_Str(Line_Params);
  886.  
  887.     Line_Params := Global_Str('Com_Line_Params');
  888.     port_num := Parse_Int('/C=',Line_Params);
  889.  
  890.     IF (Parse_Int('/P=',MParm_Str)) THEN
  891.         error := close_com(Parse_Int('/P=',MParm_Str));
  892.     END;
  893.  
  894.     error := open_com( port_num, Parse_Int('/IB=',Line_Params),
  895.             Parse_Int('/OB=',Line_Params),
  896.             Parse_Int('/I' + Str(Port_Num) + '=',Line_Params),
  897.             Parse_Int('/A' + Str(Port_Num) + '=',Line_Params));
  898.  
  899.     Already_Open := (Error = 9);
  900.     if ((error <> 0) and (Error <> 9)) then
  901. {Error 9 means com port is already open, so don't generate an error message for
  902. that.}
  903.         Set_Global_Int('Com_Port_Open',False);
  904.         Error_Level := 6000 + Error;
  905.         RM('MEERROR /EM=Error opening port ' + str(port_num));
  906.         Goto EXIT;
  907.     ELSE
  908.         Set_Global_Int('Com_Port_Num',Port_Num);
  909.         Set_Global_Int('Com_Port_Open',True);
  910.     end;
  911.     error := set_com( port_num, 1,Parse_Int('/B=',Line_Params));
  912.     error := set_com( port_num, 2,Parse_Int('/P=',Line_Params));
  913.     error := set_com( port_num, 3,Parse_Int('/D=',Line_Params));
  914.     error := set_com( port_num, 4,Parse_Int('/S=',Line_Params));
  915.     error := set_com( port_num, 5,Parse_Int('/XON=',Line_Params));
  916.     error := set_com( port_num, 6,Parse_Int('/XON=',Line_Params));
  917.     error := set_com( port_num, 9,Parse_Int('/CTS=',Line_Params));
  918.     error := set_com( port_num, 12,Parse_Int('/DTR=',Line_Params) or (Parse_Int('/RTS=',Line_Params) shl 1));
  919.     error := set_com( port_num, 13,Parse_Int('/DTR=',Line_Params) or (Parse_Int('/RTS=',Line_Params) shl 1));
  920.     error := set_com( port_num, 14,0);
  921.     error := set_com( port_num, 15,0);
  922.     IF (Already_Open) THEN
  923.         error := write_com(port_num,'|17', jx);
  924.     END;
  925.     IF (Parse_Int('/T' + Str(Port_Num) + '=',Line_Params)) THEN
  926.         IF (Global_Int('Com_Modem' + Str(Port_Num) + '_Init') = 0) THEN
  927.             error := write_com(port_num,Parse_Str('/I=',Global_Str('Com_Modem_Params')) + '|13', jx);
  928.             Set_Global_Int('Com_Modem' + Str(Port_Num) + '_Init',True);
  929.         END;
  930.     END;
  931.  
  932. EXIT:
  933. END_MACRO;
  934.  
  935. $MACRO COM_FILE TRANS;
  936. {*******************************MULTI-EDIT MACRO*******************************
  937.  
  938. Name:    COM_FILE
  939.  
  940. Description:    The comunications module macro for uploading, downloading, and
  941. dealing with the log file.
  942.  
  943. Parameters:
  944.                             /MY= The upper Y coordinate for the menu box.  Defaults to 3.
  945.                             /TP=
  946.                                      1        =            download a file
  947.                                      2        =            upload a file
  948.                                      3        =            open/close log file
  949.  
  950.                              (C) Copyright 1990 by American Cybernetics, Inc.
  951. ******************************************************************************}
  952.  
  953.     Def_Int(Menu_Y,Type,Error,Port_Num,Cursor_X,Temp_Cursor_X,Temp_Cursor_Y,
  954.                     Proto_Choice,logging,Active_Window);
  955.     Def_Str(Protocol[20],Tstr,Error_Msg,Xfer_Direction[4],Command_Line,XFer_File[40]);
  956.  
  957.     Proto_Choice := Parse_Int('/KB=',MParm_Str);
  958.     WHILE (Proto_Choice) DO
  959.         Kill_Box;
  960.         --Proto_Choice;
  961.     END;
  962.     Def_Char(T_Char);
  963.     port_num := global_int('COM_PORT_NUM');
  964.     XFer_File := '';
  965.     Temp_Cursor_X := WhereX;
  966.     Temp_Cursor_Y := WhereY;
  967.     Menu_Y := Parse_Int('MY=',MParm_Str);
  968.     IF (Menu_Y < 1) THEN
  969.         Menu_Y := 3;
  970.     END;
  971.  
  972. {Look for special parameters}
  973.     Type := Parse_Int('/TP=',MParm_Str);
  974.     IF ((Type = 1) or (Type = 2)) THEN
  975.         RM('MECOM^COM_PROTO_MENU /LO=2/X=15/Y=' +  Str(Menu_Y + 2 + Type)
  976.         + '/DU=' + Str(Type - 1));
  977.         IF (Return_Int > 0) THEN
  978.             IF (Type = 1) THEN
  979.                 Return_Str := '';
  980.                 Xfer_Direction := 'DOWN';
  981.             ELSE
  982.                 Return_Str := Parse_Str('/UP=',Global_Str('Com_General_Params'));
  983.                 Xfer_Direction := 'UP';
  984.             END;
  985.             TStr := Global_Str('COM_PROTOCOL');
  986.             IF (Parse_Int('PF=',Tstr) < 2) THEN
  987. {If no prompting for filename is configured, skip over that.}
  988.                 Return_Str := '';
  989.                 Goto SKIP_PROMPT;
  990.             END;
  991.             IF (Parse_Int('PF=',Tstr) = 2) THEN
  992. SINGLE_PROMPT:
  993.                 RM('USERIN^QUERYBOX /C=15/W=40/T=FILE TO ' + Xfer_Direction +
  994.                     'LOAD/F2=Dir   /L=' + Str(Menu_Y + 2 + Type));
  995.  
  996.                 IF (Return_Int = 0) THEN
  997.                     Goto ABORT_XFER;
  998.                 END;
  999.                 IF (Return_Int = -1) THEN
  1000.                     refresh := true;
  1001.                     fkey_row := Global_Int('Temp_fkey_row');
  1002. {
  1003.                     Message_Row := Global_Int('Temp_Message_Row');
  1004. }
  1005.                     RM('DIRSHELL /S=1');
  1006.                     fkey_row := 0;
  1007. {
  1008.                     Message_Row := 0;
  1009. }
  1010.                     refresh := false;
  1011.                     If Return_Str <> '' THEN
  1012.                         Goto SINGLE_PROMPT;
  1013.                     END;
  1014.                 END;
  1015.             END;
  1016.             IF (Parse_Int('PF=',Tstr) = 3) THEN
  1017.                 Active_Window := Window_Id;
  1018.                 Create_Window;
  1019.                 Return_Str := 'MEXFER.LST';
  1020.                 RM('Makeuserpath');
  1021.                 File_Name := Return_Str;
  1022.                 Xfer_File := Return_Str;
  1023.                 File_Changed := False;
  1024.  
  1025.                 Set_Global_Str('@XFER_EV!','/T=Dos Shell/KC=<F2>/W=13/K1=0/K2=60/R=100/MACRO=MECOM^COM_DIR_SHELL');
  1026.                 RM('USERIN^EDITWINDOW /X=9/T=CREATE A LIST OF FILES TO UPLOAD/Y='
  1027.                         + Str(Menu_Y + 2 + Type) + '/W=40/L=10/EV1=@XFER_EV!');
  1028.  
  1029.                 IF (File_Changed = False) THEN
  1030.                     Delete_Window;
  1031.                     IF (Switch_Win_Id(Active_Window)) THEN
  1032.                     END;
  1033.                     Goto ABORT_XFER;
  1034.                 END;
  1035.                 RM('VERIFY /X=9/T=Continue transfer?');
  1036.                 IF return_int = 0 THEN
  1037.                     goto abort_xfer;
  1038.                 END;
  1039. {DSZ requires a CR/LF at EOF}
  1040.                 Eof;
  1041.                 TEXT('|13|10');
  1042.                 Save_File;
  1043.  
  1044.                 Error := Error_Level;
  1045.                 Delete_Window;
  1046.                 IF (Switch_Win_Id(Active_Window)) THEN
  1047.                 END;
  1048.                 IF (Error) THEN
  1049.                     Error_Level := Error;
  1050.                     RM('MEERROR');
  1051.                     Goto ABORT_XFER;
  1052.                 END;
  1053.             END;
  1054. SKIP_PROMPT:
  1055.                 Command_Line := Parse_Str('CL=',TStr);
  1056.                 IF (Command_Line <> '') THEN
  1057.                     IF (XPos(' ',Command_Line,1) = 0) THEN
  1058.                         Command_Line := Command_Line + ' ';
  1059.                     END;
  1060.                     T_Char := Char(Parse_Int('IC=',TStr));
  1061.                     IF (T_Char <> '|0') THEN
  1062.                         error := write_com(Port_Num,T_Char,Proto_Choice);
  1063.                     END;
  1064.  
  1065.                     RM(Command_Line + '/DIR=' + Xfer_Direction + '/X=' +
  1066.                         Str(Temp_Cursor_X) + '/Y=' + Str(Temp_Cursor_Y) + '/PRO=' +
  1067.                         Parse_Str('PN=',Tstr) + '/FN=' + Return_Str + '/BATCH=' +
  1068.                         Xfer_File);
  1069.                     IF (Error_Level) THEN
  1070.                         RM('MEERROR');
  1071.                     END;
  1072.                 END;
  1073. ABORT_XFER:
  1074.                 Tstr := Global_Str('Com_Cur_Scrn_Params');
  1075.                 Set_Vp(Parse_Int('/X1=',Tstr) + 1,
  1076.                     Parse_Int('/Y1=',Tstr) + 1,
  1077.                     Parse_Int('/X2=',Tstr) - 1,
  1078.                     Parse_Int('/Y2=',Tstr) - 1);
  1079.                 Text_Color_Vp := Parse_Int('/F=',Global_Str('Com_Color_Params')) +
  1080.                                             (Parse_Int('/B=',Global_Str('Com_Color_Params')) shl 4);
  1081.         END;
  1082.     END;
  1083.  
  1084.     IF (Type = 3) THEN
  1085.         Logging := Global_Int('COM_LOGGING');
  1086.         IF (logging = 0) THEN
  1087. COM_LOG_PROMPT:
  1088.             Return_Str := Global_Str('Com_Log_File');
  1089.             RM('USERIN^QUERYBOX /C=16/W=40/ML=80/H=MECOM^FILLOG/T=LOG FILE NAME/L=' + Str(Menu_Y + 7));
  1090.             IF (RETURN_INT) THEN
  1091.                 IF (Return_Str = '') THEN
  1092.                     Beep;
  1093.                     Goto COM_LOG_PROMPT;
  1094.                 END;
  1095.                 IF (File_Exists(Return_Str)) THEN
  1096.                     RM('USERIN^XMENU /B=1/T=1/X=16/Y=' + Str(Menu_Y + 7) + '/S=1/L=LOG FILE EXISTS' +
  1097.                         '/M=Append(MECOM^FILLOG)Overwrite()aBort()');
  1098.                     IF ((Return_Int < 1) or (Return_Int = 3)) THEN
  1099.                         Goto ABORT_LOG_OPEN;
  1100.                     END;
  1101.                     IF (Return_Int = 1) THEN
  1102.                         Error := S_Open_File(Return_Str,1,Proto_Choice);
  1103.                         IF (Error) THEN
  1104.                             Return_Int := Error;
  1105.                             RM('COM_LOG_ERROR');
  1106.                             Goto ABORT_LOG_OPEN;
  1107.                         END;
  1108.                         Error := S_Move_File_Ptr(Proto_Choice,2,0);
  1109.                         IF (Error) THEN
  1110.                             Return_Int := Error;
  1111.                             RM('COM_LOG_ERROR');
  1112.                             Goto ABORT_LOG_OPEN;
  1113.                         END;
  1114.                      Goto APPEND_LOG;
  1115.                     END;
  1116.                     IF (Return_Int = 2) THEN
  1117.                         Goto NEW_LOG;
  1118.                     END;
  1119.                 ELSE
  1120. NEW_LOG:
  1121.                     Error := S_Create_File(Return_Str,Proto_Choice);
  1122.                     IF (Error) THEN
  1123.                         Return_Int := Error;
  1124.                         RM('COM_LOG_ERROR');
  1125.                         Goto ABORT_LOG_OPEN;
  1126.                     END;
  1127.                 END;
  1128. APPEND_LOG:
  1129.                 Set_Global_Int('Com_Log_Handle',Proto_Choice);
  1130. {If we are presently ASCII downloading, dump what's in the log buffer to the
  1131. ASCII file before initializing to null}
  1132.                 IF (Global_Int('Com_ASCII_Download')) THEN
  1133.                     Return_Int := Length(Global_Str('Com_Log_Str'));
  1134.                     Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Proto_Choice);
  1135.                     IF (Return_Int > Proto_Choice) THEN
  1136.                         Return_Int := 241;
  1137.                         RM('COM_LOG_ERROR /A=1');
  1138.                     END;
  1139.                     IF (Error) THEN
  1140.                         Return_Int := Error;
  1141.                         RM('COM_LOG_ERROR /A=1');
  1142.                     END;
  1143.                 END;
  1144.  
  1145.                 Set_Global_Str('Com_Log_Str','');
  1146.                 Set_Global_Str('Com_Log_File',Return_Str);
  1147.                 Set_Global_Int('Com_Logging',True);
  1148.                 Set_Global_Int('Com_First_Log',False);
  1149.                 Goto EXIT;
  1150.             ELSE
  1151. ABORT_LOG_OPEN:
  1152.                 Goto EXIT;
  1153.             END;
  1154.         END;
  1155.         IF (Logging) THEN
  1156.             Return_Int := Length(Global_Str('Com_Log_Str'));
  1157.             Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Proto_Choice);
  1158.             IF (Return_Int > Proto_Choice) THEN
  1159.                 Return_Int := 241;
  1160.                 RM('COM_LOG_ERROR');
  1161.                 Goto ABORT_LOG_CLOSE;
  1162.             END;
  1163.             IF (Error) THEN
  1164.                 Return_Int := Error;
  1165.                 RM('COM_LOG_ERROR');
  1166.                 Goto ABORT_LOG_CLOSE;
  1167.             END;
  1168.             Error := S_Close_File(Global_Int('Com_Log_Handle'));
  1169.             IF (Error) THEN
  1170.                 Return_Int := Error;
  1171.                 RM('COM_LOG_ERROR');
  1172.             END;
  1173. ABORT_LOG_CLOSE:
  1174.             Set_Global_Int('Com_Logging',False);
  1175.         END;
  1176.     END;
  1177.     Goto EXIT;
  1178.  
  1179. EXIT:
  1180. END_MACRO;
  1181.  
  1182. $MACRO COM_XFER_BEEP TRANS;
  1183. {*******************************MULTI-EDIT MACRO*******************************
  1184.  
  1185. Name:    COM_XFER_BEEP
  1186.  
  1187. Description:    Called by any file transfer macro.  Determines if the "Beep on
  1188.                             uploads and downloads" option is enabled and beeps if it is.
  1189.  
  1190.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1191. ******************************************************************************}
  1192.  
  1193.     IF (Parse_Int('/A=',Global_Str('Com_General_Params')) <> 0) THEN
  1194.         RM('MEERROR^BEEPS /C=2/D=500/F=250/P=250');
  1195.     END;
  1196. END_MACRO;
  1197.  
  1198. $MACRO COM_LOG_ERROR TRANS;
  1199. {*******************************MULTI-EDIT MACRO*******************************
  1200.  
  1201. Name:    COM_LOG_ERROR
  1202.  
  1203. Description:    An error handler for disk I/O errors relating the log or ASCII
  1204.                             downloads.
  1205.  
  1206. Parameters:
  1207.                             /A=    If 1 then error message will be for ASCII upload else for
  1208.                                     Log.
  1209.                             Return_Int = the error number.
  1210.  
  1211.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1212. ******************************************************************************}
  1213.     IF (Parse_Int('/A=',MParm_Str)) THEN
  1214.         Return_Str := 'ASCII Upload';
  1215.         IF (S_Close_File(Global_Int('Com_ASCII_Handle'))) THEN END;
  1216.         Set_Global_Int('Com_ASCII_Download',False);
  1217.     ELSE
  1218.         Return_Str := 'Log';
  1219.         IF (S_Close_File(Global_Int('Com_Log_Handle'))) THEN END;
  1220.         Set_Global_Int('Com_Logging',False);
  1221.     END;
  1222.     Set_Global_Str('Com_Log_Str','');
  1223.     Error_Level := Return_Int;
  1224.     IF (Return_Int = 241) THEN
  1225.         RM('MEERROR /EM=' + Copy('ASCII UploadLog',((Parse_Int('/A=',MParm_Str) = 0) * 12) + 1,12) + ' file disk full error.  File has been closed.');
  1226.     ELSE
  1227.         RM('MEERROR /EM=' + Copy('ASCII UploadLog',((Parse_Int('/A=',MParm_Str) = 0) * 12) + 1,12) + ' file disk error #' + str(3000 + Return_Int) + '.  File has been closed.');
  1228.     END;
  1229.  
  1230. END_MACRO;
  1231.  
  1232. $MACRO COM_QUIT TRANS;
  1233. {*******************************MULTI-EDIT MACRO*******************************
  1234.  
  1235. Name:    COM_QUIT
  1236.  
  1237. Description:    The comunications module quit prompt.
  1238.  
  1239. Parameters:
  1240.                             /X=    The upper left corner X coordinate of the menu box.
  1241.                             /Y=    The upper left corner Y coordinate of the menu box.
  1242.  
  1243. Returns:
  1244.                             Return_Str = '/QUIT=1' if <ESC> is not pressed.  This return_Str is
  1245.                             to tell the com main program to exit the com module.
  1246.  
  1247.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1248. ******************************************************************************}
  1249.     Def_Int(T_Int,Port_Num);
  1250.  
  1251.     Return_Str := '';
  1252.     Create_Global_Str('COMQUITSTR_1','/H=MECOM^QUI');
  1253.     Create_Global_Str('XCOMQUITSTR_1','Yes');
  1254.     Create_Global_Str('COMQUITSTR_2','');
  1255.     Create_Global_Str('XCOMQUITSTR_2','No');
  1256.  
  1257.     RM('USERIN^SUBMENU /M=XCOMQUITSTR_/G=COMQUITSTR_/#=2/S=1/L=CLOSE COM PORT?/X='
  1258.         + Parse_Str('/X=',MParm_Str) + '/GCLR=1/Y=' + Parse_Str('/Y=',MParm_Str));
  1259.  
  1260.     IF (Return_Int) THEN
  1261.         Port_Num := Global_Int('Com_port_num');
  1262.         IF (Return_Int = 1) THEN
  1263.             T_Int := (close_com(Port_Num));
  1264.         ELSE
  1265. {If port is to remain open, Send XOFF}
  1266.             T_Int := (write_com(port_num,'|19',T_Int));
  1267.             IF (Parse_Int('/T' + Str(Port_Num) + '=',Global_Str('Com_Line_Params')) = 0) THEN
  1268. {If this is not connected to a modem, drop DTR}
  1269.                 T_Int := set_com(port_num, 13,Parse_Int('/RTS=',Global_Str('Com_Line_Params')) shl 1);
  1270.             END;
  1271.         END;
  1272.         IF (Return_Int > 0) THEN
  1273.             Return_Str := '/QUIT=1';
  1274.         END;
  1275.         Set_Global_Int('Com_Port_Open',(Return_Int <> 1));
  1276.     END;
  1277. END_MACRO;
  1278.  
  1279. $MACRO COM_ASCII_DOWN TRANS;
  1280. {*******************************MULTI-EDIT MACRO*******************************
  1281.  
  1282. Name:    COM_ASCII_DOWN
  1283.  
  1284. Description:    The comunications module ASCII download macro.
  1285.  
  1286. Parameters:
  1287.                             /QUIT= If 1, then terminate the download. If 0, then begin.
  1288.                             /APPEND= If 1, then append the file rather than overwrite.
  1289.                             /OVERWRITE= Unconditionally overwrites without prompting.
  1290.                             Return_Str= The file name.
  1291.  
  1292.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1293. ******************************************************************************}
  1294.     Def_Int(ASCII_Handle,Error,Bytes_Written);
  1295.  
  1296. {We are going use the log file buffer, so if it is active, save and flush.}
  1297.     IF (Global_Int('Com_Logging')) THEN
  1298.         Return_Int := Length(Global_Str('Com_Log_Str'));
  1299.         Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Bytes_Written);
  1300.         IF (Return_Int > Bytes_Written) THEN
  1301.             Return_Int := 241;
  1302.             RM('COM_LOG_ERROR');
  1303.             Goto EXIT;
  1304.         END;
  1305.         IF (Error) THEN
  1306.             Return_Int := Error;
  1307.             RM('COM_LOG_ERROR');
  1308.             Goto EXIT;
  1309.         END;
  1310.     END;
  1311.     IF (Parse_Int('/QUIT=',MParm_Str)) THEN
  1312.         IF (Global_Int('Com_ASCII_Download')) THEN
  1313.             Return_Int := Length(Global_Str('Com_Log_Str'));
  1314.             Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Bytes_Written);
  1315.             IF (Return_Int > Bytes_Written) THEN
  1316.                 Return_Int := 241;
  1317.                 RM('COM_LOG_ERROR /A=1');
  1318.             END;
  1319.             IF (Error) THEN
  1320.                 Return_Int := Error;
  1321.                 RM('COM_LOG_ERROR /A=1');
  1322.             END;
  1323.             Error := S_Close_File(Global_Int('Com_ASCII_Handle'));
  1324.             IF (Error) THEN
  1325.                 Return_Int := Error;
  1326.                 RM('COM_LOG_ERROR /A=1');
  1327.             END;
  1328.             Set_Global_Int('Com_ASCII_Handle',0);
  1329.             Set_Global_Int('Com_ASCII_Download',False);
  1330.             Set_Global_Str('COM_ASCII_FILENAME','');
  1331.         END;
  1332. {If they pressed the ASCII download terminate key, but were not downloading, pass
  1333. the keystroke to the com port if it is a meaningful keystroke}
  1334.         IF (Key1 <> 0) THEN
  1335.             error := write_com(Global_int('Com_Port_Num'),Char(Key1),Bytes_Written);
  1336.         END;
  1337.  
  1338.         Goto EXIT;
  1339.     END;
  1340.     IF (File_Exists(Return_Str)) THEN
  1341.             IF (Parse_Int('/APPEND=',MParm_Str)) THEN
  1342.                 Error := S_Open_File(Return_Str,1,Ascii_Handle);
  1343.                 IF (Error) THEN
  1344.                     Return_Int := Error;
  1345.                     RM('COM_LOG_ERROR /A=1');
  1346.                     Goto EXIT;
  1347.                 END;
  1348.                 Error := S_Move_File_Ptr(ASCII_Handle,2,0);
  1349.                 Goto APPEND;
  1350.             ELSIF (Parse_Int('/OVERWRITE=',MParm_Str) = False) THEN
  1351.                 RM('userin^VERIFY /L=10/C=10/H=MECOM^FILLOG/T=The file ' + Caps(Truncate_Path(Return_Str)) + ' already exists.  Overwrite?');
  1352.                 IF (Return_Int <> 1) THEN
  1353.                     Goto EXIT;
  1354.                 END;
  1355.             END;
  1356.     END;
  1357.     Error := S_Create_File(Return_Str,ASCII_Handle);
  1358. APPEND:
  1359.     IF (Error) THEN
  1360.         Return_Int := Error;
  1361.         RM('COM_LOG_ERROR /A=1');
  1362.         Goto EXIT;
  1363.     END;
  1364.  
  1365.     Set_Global_Int('Com_ASCII_Handle',ASCII_Handle);
  1366.     Set_Global_Int('Com_ASCII_Download',True);
  1367.     Set_Global_Str('COM_ASCII_FILENAME',Return_Str);
  1368.  
  1369. EXIT:
  1370.     Set_Global_Str('Com_Log_Str','');
  1371.     Return_Int := 100;
  1372.  
  1373. END_MACRO;
  1374.  
  1375. $MACRO COM_ASCII_UP TRANS;
  1376. {*******************************MULTI-EDIT MACRO*******************************
  1377.  
  1378. Name:    COM_ASCII_UP
  1379.  
  1380. Description:    The comunications module ASCII upload macro.
  1381.  
  1382. Parameters:
  1383.                             /X= The X coordinate for the cursor to be positioned during the
  1384.                                     upload.
  1385.                             /X= The Y coordinate for the cursor.
  1386.  
  1387.                             /FN= The file name to upload.
  1388.  
  1389. Returns:
  1390.                             Return_Int = Error level if an error occurred.
  1391.  
  1392.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1393. ******************************************************************************}
  1394.  
  1395.     Def_Int(Timeout_Count,Port_Num,Error,Jx,Carriage_Return,Line_Feed,Pace_Char,
  1396.                     Line_Pacing,Char_Pacing,Expand_Blanks,Echo,Added_LF,Out_Pointer);
  1397.     Def_Int(Buf_Length,CR_Pos,Pointer,File_Handle);
  1398.     Def_Str(File_Buf[2048],F_Name,Line_Out[2048],In_Buf,Term_Mac[25]);
  1399.     Def_Char(Ch, In_Ch);
  1400.  
  1401. {Variables for special elapsed time code
  1402.     Def_Int(Start_Minutes,Start_Seconds,End_Minutes,End_Seconds);
  1403. }
  1404.     WRITE('  ASCII UPLOADING  ',44,Global_Int('COM_STATUS_ROW'),0,Working_Color);
  1405.     GotoXY(Parse_Int('/X=',MParm_Str),Parse_Int('/Y=',MParm_Str));
  1406.     Port_Num := Global_int('Com_Port_Num');
  1407.     Carriage_Return := Parse_Int('/CU=',Global_Str('Com_Ascii_Params'));
  1408.     Line_Feed := Parse_Int('/LU=',Global_Str('Com_Ascii_Params'));
  1409.     Line_Pacing := Parse_Int('/LP=',Global_Str('Com_Ascii_Params')) * 10;
  1410.     Pace_Char := Parse_Int('/PC=',Global_Str('Com_Ascii_Params'));
  1411.     Char_Pacing := Parse_Int('/CP=',Global_Str('Com_Ascii_Params'));
  1412.     Expand_Blanks := Parse_Int('/S=',Global_Str('Com_Ascii_Params'));
  1413.     Echo := Parse_Int('/E=',Global_Str('Com_Ascii_Params'));
  1414.     In_Buf := '';
  1415.     Term_Mac := 'MECOM^COM_' + Parse_Str('/T=',Global_Str('Com_Terminal_Params'))
  1416.                             + ' /DO=';
  1417.  
  1418.     IF (S_Open_File(Parse_Str('/FN=',MParm_Str),0,File_Handle)) THEN
  1419.         Return_Int := 3;
  1420.         Goto OPEN_ERROR;
  1421.     END;
  1422. {special development code for calculating elapsed time
  1423. If ((Val(Start_Minutes,Copy(Time,4,2))) and (Val(Start_Seconds,Copy(Time,7,2)))) Then
  1424. End;
  1425. }
  1426. MORE_FILE:
  1427.     IF (S_Read_Bytes(File_Buf,File_Handle,2048)) THEN
  1428.         Return_Int := 3;
  1429.         Goto ABORT;
  1430.     END;
  1431.     Buf_Length := Svl(File_Buf);
  1432.  
  1433.     Call PARSE_BUF;
  1434.  
  1435.     IF (Buf_Length = 2048) THEN
  1436.         Goto MORE_FILE;
  1437.     END;
  1438.     Goto DONE;
  1439.  
  1440. PARSE_BUF:
  1441.     Pointer := 1;
  1442.  
  1443. MORE_LINES:
  1444.     CR_Pos := XPos('|13',File_Buf,Pointer);
  1445.     IF (Cr_Pos = 0) THEN
  1446.         CR_Pos := Buf_Length;
  1447.     ELSE
  1448.         IF (XPos('|10',File_Buf,Cr_Pos) = (Cr_Pos + 1)) THEN
  1449.             ++Cr_Pos;
  1450.         END;
  1451.     END;
  1452.  
  1453.     Line_Out := Copy(File_Buf,Pointer,Cr_Pos - Pointer + 1);
  1454.  
  1455.     IF (Expand_Blanks) THEN
  1456. {If this is a blank line, then expand it if Expand_Blanks is turned on}
  1457.         IF (Str_Char(Line_Out,1) = '|13') THEN
  1458.             Line_Out := ' ' + Line_Out;
  1459.         END;
  1460.     END;
  1461.  
  1462. {If any filtering needs to be done, do it.}
  1463.     Added_Lf := 0;
  1464.     IF (Carriage_Return > 0) THEN
  1465. FILTER_CR:
  1466.         Jx := XPos('|13',Line_Out,1);
  1467.         IF (Jx) THEN
  1468.             IF (Carriage_Return = 2) THEN
  1469. {Strip CR}
  1470.                 Line_Out := Str_Del(Line_Out,Jx,1);
  1471.                 Goto FILTER_CR;
  1472.             END;
  1473.             IF (Carriage_Return = 1) THEN
  1474. {Add a LF}
  1475.                 Line_Out := Line_Out + '|10';
  1476. {Use this as a flag to indicate to the LF filtering not to process}
  1477.                 Added_Lf := SVL(Line_Out);
  1478.             END;
  1479.         END;
  1480.     END;
  1481.     IF (Line_Feed > 0) THEN
  1482. FILTER_LF:
  1483.         Jx := XPos('|10',Line_Out,1);
  1484.         IF (Jx > Added_Lf) THEN
  1485.             IF (Line_Feed = 2) THEN
  1486. {Strip LF}
  1487.                 Line_Out := Str_Del(Line_Out,Jx,1);
  1488.                 Goto FILTER_LF;
  1489.             END;
  1490.             IF (Line_Feed = 1) THEN
  1491. {Add CR}
  1492.                 Line_Out := Str_Ins('|13',Line_Out,Jx + 1);
  1493.             END;
  1494.         END;
  1495.     END;
  1496.  
  1497.     IF (Echo) THEN
  1498.         RM(Term_Mac + Line_Out);
  1499.     END;
  1500.  
  1501.     IF (Char_Pacing > 0) THEN
  1502.         Call SEND_CHARS;
  1503.     ELSE
  1504. SEND_LINE:
  1505.         error := write_com(port_num,Line_Out,Jx);
  1506.         IF (Check_Key) THEN
  1507.             IF (Key1 = 27) THEN
  1508.                 Return_Int := 1;
  1509.                 Goto ABORT;
  1510.             END;
  1511.         END;
  1512.         IF (Jx < Svl(Line_Out)) THEN
  1513. {If the whole line didn't get sent, try sending the remainder of the line}
  1514.             Line_Out := Copy(Line_Out,Jx + 1,2048);
  1515.             Goto SEND_LINE;
  1516.         END;
  1517.     END;
  1518.  
  1519. LINE_SENT:
  1520.     Delay(Char_Pacing);
  1521.     Call CHECK_FOR_REMOTE;
  1522.     Pointer := Cr_Pos + 1;
  1523.     Delay(Line_Pacing);
  1524.     IF (Pace_Char) THEN
  1525.         Call CHECK_FOR_PACE_CHAR;
  1526.     ELSE
  1527.         Call CHECK_FOR_REMOTE;
  1528.     END;
  1529.  
  1530.     IF (Pointer < Buf_Length) THEN
  1531.         Goto MORE_LINES;
  1532.     END;
  1533.     RET;
  1534.  
  1535. SEND_CHARS:
  1536.     Out_Pointer := 0;
  1537.     WHILE (Out_Pointer < Svl(Line_Out)) DO
  1538.         ++Out_Pointer;
  1539. CHAR_AGAIN:
  1540.         error := write_com(port_num,Copy(Line_Out,Out_Pointer,1),Jx);
  1541.         IF (Check_Key) THEN
  1542.             IF (Key1 = 27) THEN
  1543.                 Return_Int := 1;
  1544.                 Goto ABORT;
  1545.             END;
  1546.         END;
  1547.         Delay(Char_Pacing);
  1548.         Call CHECK_FOR_REMOTE;
  1549.         IF (Jx = 0) THEN
  1550.             Goto CHAR_AGAIN;
  1551.         END;
  1552.     END;
  1553.     Ret;
  1554.  
  1555. CHECK_FOR_REMOTE:
  1556.         WHILE (read_com(port_num, In_Ch) = 0) DO
  1557.             IF (Svl(In_Buf) > 253) THEN
  1558.                 RM(Term_Mac + In_Buf);
  1559.                 In_Buf := In_Ch;
  1560.             ELSE
  1561.                 In_Buf := In_Buf + In_Ch;
  1562.             END;
  1563.             Delay(Char_Pacing);
  1564.         END;
  1565.         IF (Svl(In_Buf)) THEN
  1566.             RM(Term_Mac + In_Buf);
  1567.         END;
  1568.         In_Buf := '';
  1569.         RET;
  1570.  
  1571. CHECK_FOR_PACE_CHAR:
  1572.  
  1573. WAIT:
  1574.     IF (Check_Key) THEN
  1575.         IF (Key1 = 27) THEN
  1576.             Return_Int := 1;
  1577.             Goto ABORT;
  1578.         END;
  1579.     END;
  1580.     IF (read_com(port_num, In_Ch) = 0) THEN
  1581.         IF (In_Ch = Char(Pace_Char)) THEN
  1582.             IF (Svl(In_Buf)) THEN
  1583.                 RM(Term_Mac + In_Buf);
  1584.             END;
  1585.             In_Buf := '';
  1586.             Ret;
  1587.         ELSE
  1588.             IF (Svl(In_Buf) > 253) THEN
  1589.                 RM(Term_Mac + In_Buf);
  1590.                 In_Buf := In_Ch;
  1591.             ELSE
  1592.                 In_Buf := In_Buf + In_Ch;
  1593.             END;
  1594.         END;
  1595.     END;
  1596.     Goto WAIT;
  1597.  
  1598. DONE:
  1599. {special development code to determine elapsed time
  1600. If ((Val(End_Minutes,Copy(Time,4,2))) and (Val(End_Seconds,Copy(Time,7,2)))) Then
  1601. End;
  1602. If (Start_Seconds > End_Seconds) Then
  1603.     End_Seconds := End_Seconds + 60;
  1604.     --End_Minutes;
  1605. End;
  1606. If (Start_Minutes > End_Minutes) Then
  1607.     End_Minutes := End_Minutes + 60;
  1608. End;
  1609. Write_VP('Elapsed time ' + Str(End_Minutes - Start_Minutes) + ':' + Str(End_Seconds - Start_Seconds) + '|13|10');
  1610. Read_Key;
  1611. }
  1612.     Call CHECK_FOR_REMOTE;
  1613.     Return_Int := False;
  1614.  
  1615. ABORT:
  1616. {Close the file}
  1617.     Error := S_Close_File(File_Handle);
  1618.  
  1619. OPEN_ERROR:
  1620.     IF (Return_Int) THEN
  1621.         Error_Level := Return_Int;
  1622.         RM('MEERROR /EM=ASCII upload error ' + str(Error_Level));
  1623.     END;
  1624.  
  1625.     Return_Str := '/DRC=1';
  1626. END_MACRO;
  1627.  
  1628. $MACRO COM_PROTO_MENU;
  1629. {*******************************MULTI-EDIT MACRO*******************************
  1630.  
  1631. Name:    COM_PROTO_MENU
  1632.  
  1633. Description:    This macro creates a special menu of file transfer protocols.
  1634.  
  1635. Parameters:
  1636.                             /X=    The upper left corner X coordinate of the menu box.
  1637.                             /Y=    The upper left corner Y coordinate of the menu box.
  1638.                             /DU= If 0 then download.  If 1 then upload.
  1639.                             /LO= List only.  If 1, just bring up the menu.  Don't allow
  1640.                                      editing of menu choices.
  1641.  
  1642.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1643. ******************************************************************************}
  1644.  
  1645.     Def_Int(X,Y);
  1646.     Def_Str(Direction[8]);
  1647.  
  1648.     Direction := Copy('DOWNLOADUPLOAD',(Parse_Int('/DU=',MParm_Str) * 8) + 1,8);
  1649.     X := Parse_Int('/X=',MParm_Str);
  1650.     IF (X = 0) THEN
  1651.         X := 3;
  1652.     END;
  1653.     Y := Parse_Int('/Y=',MParm_Str);
  1654.     IF (Y = 0) THEN
  1655.         Y := 3;
  1656.     END;
  1657.  
  1658.     RM('USERIN^DB /GLO=COM_PROTOCOL/LO=' + Parse_Str('/LO=',MParm_Str) +
  1659.         '/PRE=PROTO/NOALPHA=1/NDF=1/ENC=1/X=' + Str(X) + '/F=MECOM.DB' +
  1660.         '/Y=' + Str(Y) + '/DPT=' + Direction + '.DB/LT=' +
  1661.         Direction + ' PROTOCOLS/HPT=DOWNLOAD.DB/DT=' + Direction +
  1662.         ' PROTOCOL MACRO SETUP/H=MECOM^SETDNL');
  1663.  
  1664.     IF (Return_Int = 0) THEN
  1665.         Set_Global_Str('COM_PROTOCOL','');
  1666.     END;
  1667.  
  1668. EXIT:
  1669.  
  1670. END_MACRO;
  1671.  
  1672. $MACRO COM_SETUP TRANS;
  1673. {*******************************MULTI-EDIT MACRO*******************************
  1674.  
  1675. Name:    COM_SETUP
  1676.  
  1677. Description:    The comunications module installation and setup macro.
  1678.  
  1679. Parameters:
  1680.                             /X=    The upper left corner X coordinate reference point.
  1681.                             /Y=    The upper left corner Y coordinate reference point.
  1682.                             /TP=
  1683.                                             1  -  General parameters
  1684.                                             2  -  modem parameters
  1685.                                             3  -  terminal parameters
  1686.                                             4  -  line parameters
  1687.                                             5  -  screen parameters
  1688.                                             6  -  download protocols
  1689.                                             7  -  upload protocols
  1690.                                             8  -  Ascii parameters
  1691.                                             10  -  save setup
  1692.  
  1693. Returns:
  1694.                             Global_Int('COM_CHANGES_MADE')
  1695.                             If not 0 then parse out the following bits:
  1696.                                 Bit 0 = changed general parameters
  1697.                                 Bit 1 = changed modem parameters
  1698.                                 Bit 2 = changed terminal parameters
  1699.                                 Bit 3 = changed port parameters
  1700.                                 Bit 4 = changed screen parameters
  1701.                                 Bit 5 = changed ascii parameters
  1702.                             Return_Int
  1703.                                 Only useful to SUBMENU.  Tells whether or not to kill all the
  1704.                                 boxes.
  1705.  
  1706.                              (C) Copyright 1990 by American Cybernetics, Inc.
  1707. ******************************************************************************}
  1708.  
  1709.     def_str(X_Str[2],Y_Str[2],B_Str[10],Direction[8],G_Str,H_Str[30],MStr);
  1710.     def_int(jx,Sub_Choice,Menu_X,Menu_Y,T_Fore,T_Back,Changes_Made,Type,Start_Line,Search_Amount);
  1711.  
  1712.     Menu_X := Parse_Int('/X=',MParm_Str);
  1713.     Menu_Y := Parse_Int('/Y=',MParm_Str);
  1714.     IF (Menu_X < 1) THEN
  1715.         Menu_X := 1;
  1716.     END;
  1717.     IF (Menu_Y < 9) THEN
  1718.         Menu_Y := 9;
  1719.     END;
  1720.  
  1721.     Type := Parse_Int('/TP=',MParm_Str);
  1722.     X_Str := Str(Menu_X);
  1723.     Y_Str := Str(Menu_Y + Type - 8);
  1724.  
  1725.     Changes_Made := Global_Int('COM_CHANGES_MADE');
  1726.  
  1727. {If we don't have a window for the MECOM.DB, create one.}
  1728.     IF (Switch_Win_Id(Global_Int('Com_Init_Window')) = 0) THEN
  1729.         Switch_Window(Window_Count);
  1730.         Create_Window;
  1731.         Set_Global_Int('Com_Init_Window',Window_ID);
  1732.         return_str := 'MECOM.DB';
  1733.         RM('MakeUserPath /DF=1');
  1734.         Load_File(Return_Str);
  1735. {If this file is empty, abort this sucker!}
  1736.         IF (At_Eof) THEN
  1737.             Error_Level := 3002;
  1738.             RM('MEERROR /EM=CAN''T FIND: ' + Return_Str + ', OR FILE IS EMPTY!  ABORTING MECOM SETUP.  PLEASE EXIT MECOM AND CORRECT THIS PROBLEM.');
  1739.             Goto EXIT;
  1740.         END;
  1741. {Find the page title INITCOM.ME or create if not there}
  1742.         IF (Search_Fwd('|12INITCOM.ME',0) = 0) THEN
  1743.             Eof;
  1744.             IF (C_Col > 1) THEN
  1745.                 Down;
  1746.             END;
  1747.             Put_Line('|12INITCOM.ME');
  1748.         END;
  1749. {Save the beginning position}
  1750.         Start_Line := C_Line;
  1751.         Eol;
  1752. {Find the next page title or EOF}
  1753.         IF (Search_Fwd('|12',0) = 0) THEN
  1754.             Eof;
  1755.             IF (C_Col > 1) THEN
  1756.                 Down;
  1757.             END;
  1758.         END;
  1759.         Search_Amount := C_Line - Start_Line;
  1760.     ELSE
  1761.         Start_Line := Parse_Int('/SL=',Global_Str('COM_INIT_WINDOW'));
  1762.         Search_Amount := Parse_Int('/SA=',Global_Str('COM_INIT_WINDOW'));
  1763.     END;
  1764.     window_attr := $81;
  1765.  
  1766.     IF (Type = 1) THEN
  1767.         Call SETUP_GENERAL;
  1768.     END;
  1769.     IF (Type = 2) THEN
  1770.         Call SETUP_MODEM;
  1771.     END;
  1772.     IF (Type = 3) THEN
  1773.         Call SETUP_TERMINAL;
  1774.     END;
  1775.     IF (Type = 4) THEN
  1776.         Call SETUP_PORT;
  1777.     END;
  1778.     IF (Type = 5) THEN
  1779.         Call SETUP_SCREEN;
  1780.     END;
  1781.     IF ((Type = 6) or (Type = 7)) THEN
  1782.         Direction := Copy('DOWNLOADUPLOAD',((Type - 6) * 8) + 1,8);
  1783.         Call SETUP_PROTOCOL;
  1784.     END;
  1785.     IF (Type = 8) THEN
  1786.         Call SETUP_ASCII;
  1787.     END;
  1788.     IF (Type = 10) THEN
  1789.         Call SAVE_SETUP;
  1790.     END;
  1791.     Goto EXIT;
  1792. {********************************** SUBROUTINES ******************************}
  1793. SETUP_GENERAL:
  1794.     G_Str := Global_Str('Com_General_Params');
  1795.     Set_Global_Str('ISTR_1',Parse_Str('/DP=',G_Str));
  1796.     Set_Global_Str('IPARM_1','/C=1/L=1/W=44/H=MECOM^SETGEN/T=Download path                  ');
  1797.     Set_Global_Str('ISTR_2',Parse_Str('/UP=',G_Str));
  1798.     Set_Global_Str('IPARM_2','/C=1/L=2/W=44/H=MECOM^SETGEN/T=Upload path                    ');
  1799.     Set_Global_Str('ISTR_3',Parse_Str('/LF=',G_Str));
  1800.     Set_Global_Str('IPARM_3','/C=1/L=3/W=44/ML=80/H=MECOM^SETGEN/T=Log File                       ');
  1801.     Set_Global_Str('ISTR_4','/T=On/F=Off');
  1802.     Set_Global_Int('IINT_4',Parse_Int('/A=',G_Str));
  1803.     Set_Global_Str('IPARM_4','/C=1/L=4/W=3/H=MECOM^SETGEN/TP=5/T=Beep on downloads and uploads  ');
  1804.     Set_Global_Str('ISTR_5','/T=On/F=Off');
  1805.     Set_Global_Int('IINT_5',Parse_Int('/VWW=',G_Str));
  1806.     Set_Global_Str('IPARM_5','/C=1/L=5/W=3/H=MECOM^SETGEN/TP=5/T=Word wrap in file viewer       ');
  1807.     Set_Global_Int('IINT_6',Parse_Int('/VRM=',G_Str));
  1808.     Set_Global_Str('IPARM_6','/TP=1/C=1/L=6/W=4/H=MECOM^SETGEN/T=Right margin for file viewer   ');
  1809.     Set_Global_Str('ISTR_7','/T=On/F=Off');
  1810.     Set_Global_Int('IINT_7',Parse_Int('/MWW=',G_Str));
  1811.     Set_Global_Str('IPARM_7','/C=1/L=7/W=3/H=MECOM^SETGEN/TP=5/T=Word wrap in message editor    ');
  1812.     Set_Global_Int('IINT_8',Parse_Int('/MRM=',G_Str));
  1813.     Set_Global_Str('IPARM_8','/TP=1/C=1/L=8/W=4/H=MECOM^SETGEN/T=Right margin for message editor');
  1814.  
  1815.     RM( 'USERIN^DATA_IN /A=2/#=8/S=1/X=3/T=GENERAL SETUP/X=' + X_Str +
  1816.         '/Y=' + Y_Str);
  1817.  
  1818.     IF (Return_Int) THEN
  1819.         Changes_Made := Changes_Made or $01;
  1820. {be sure trailing '\' is included on D/L and U/L path}
  1821.         IF (Global_Str('ISTR_1') <> '') THEN
  1822.             IF (Copy(Global_Str('ISTR_1'),Length(Global_Str('ISTR_1')),1) <> '\') THEN
  1823.                 Set_Global_Str('ISTR_1',Global_Str('ISTR_1') + '\');
  1824.             END;
  1825.         END;
  1826.         IF (Global_Str('ISTR_2') <> '') THEN
  1827.             IF (Copy(Global_Str('ISTR_2'),Length(Global_Str('ISTR_2')),1) <> '\') THEN
  1828.                 Set_Global_Str('ISTR_2',Global_Str('ISTR_2') + '\');
  1829.             END;
  1830.         END;
  1831.         Set_Global_Str('Com_General_Params','/GENERAL=' +
  1832.             '/DP=' + Caps(Global_Str('ISTR_1')) +
  1833.             '/UP=' + Caps(Global_Str('ISTR_2')) +
  1834.             '/LF=' + Caps(Global_Str('ISTR_3')) +
  1835.             '/A=' + Str(Global_Int('IINT_4')) +
  1836.             '/VWW=' + Str(Global_Int('IINT_5')) +
  1837.             '/VRM=' + Str(Global_Int('IINT_6')) +
  1838.             '/MWW=' + Str(Global_Int('IINT_7')) +
  1839.             '/MRM=' + Str(Global_Int('IINT_8'))
  1840.             );
  1841.     END;
  1842.     Ret;
  1843.  
  1844. SETUP_MODEM:
  1845.     G_Str := Global_Str('Com_Modem_Params');
  1846.     Set_Global_Str('ISTR_1',Parse_Str('/XP=',G_Str));
  1847.     Set_Global_Str('IPARM_1','/C=1/L=1/W=1/H=MECOM^SETMOD/T=2 second pause substitute character ');
  1848.     Set_Global_Str('ISTR_2',Parse_Str('/XC=',G_Str));
  1849.     Set_Global_Str('IPARM_2','/C=1/L=2/W=1/H=MECOM^SETMOD/T=Carriage return substitute character');
  1850.     Set_Global_Str('ISTR_3',Parse_Str('/XT=',G_Str));
  1851.     Set_Global_Str('IPARM_3','/C=1/L=3/W=1/H=MECOM^SETMOD/T=Control substitute character        ');
  1852.     Set_Global_Str('ISTR_4',Parse_Str('/XE=',G_Str));
  1853.     Set_Global_Str('IPARM_4','/C=1/L=4/W=1/H=MECOM^SETMOD/T=Escape substitute character         ');
  1854.     Set_Global_Str('ISTR_5',Parse_Str('/I=',G_Str));
  1855.     Set_Global_Str('IPARM_5','/C=1/L=5/W=37/H=MECOM^SETMOD/T=Modem initialization command        ');
  1856.     Set_Global_Str('ISTR_6',Parse_Str('/DC=',G_Str));
  1857.     Set_Global_Str('IPARM_6','/C=1/L=6/W=37/H=MECOM^SETMOD/T=Dialing command prefix              ');
  1858.     Set_Global_Str('ISTR_7',Parse_Str('/DS=',G_Str));
  1859.     Set_Global_Str('IPARM_7','/C=1/L=7/W=37/H=MECOM^SETMOD/T=Dialing command suffix              ');
  1860.     Set_Global_Str('ISTR_8',Parse_Str('/H=',G_Str));
  1861.     Set_Global_Str('IPARM_8','/C=1/L=8/W=37/H=MECOM^SETMOD/T=Hangup command                      ');
  1862.     Set_Global_Str('ISTR_9','/F=Send hangup command/T=Drop DTR');
  1863.     Set_Global_Int('IINT_9',Parse_Int('/HM=',G_Str));
  1864.     Set_Global_Str('IPARM_9','/TP=5/C=1/L=9/W=19/H=MECOM^SETMOD/T=Hangup method                       ');
  1865.     Set_Global_Int('IINT_10',Parse_Int('/RT=',G_Str));
  1866.     Set_Global_Str('IPARM_10','/TP=1/C=1/L=10/W=2/H=MECOM^SETMOD/T=Redial timeout                      ');
  1867.     Set_Global_Int('IINT_11',Parse_Int('/RP=',G_Str));
  1868.     Set_Global_Str('IPARM_11','/TP=1/C=1/L=11/W=2/H=MECOM^SETMOD/T=Redial pause                        ');
  1869.     Set_Global_Str('ISTR_12',Parse_Str('/CS=',G_Str));
  1870.     Set_Global_Str('IPARM_12','/C=1/L=12/W=37/H=MECOM^SETMOD/T=Modem connect response              ');
  1871.     Set_Global_Str('ISTR_13',Parse_Str('/NC1=',G_Str));
  1872.     Set_Global_Str('IPARM_13','/C=1/L=13/W=37/H=MECOM^SETMOD/T=Modem no connect response 1         ');
  1873.     Set_Global_Str('ISTR_14',Parse_Str('/NC2=',G_Str));
  1874.     Set_Global_Str('IPARM_14','/C=1/L=14/W=37/H=MECOM^SETMOD/T=Modem no connect response 2         ');
  1875.     Set_Global_Str('ISTR_15',Parse_Str('/NC3=',G_Str));
  1876.     Set_Global_Str('IPARM_15','/C=1/L=15/W=37/H=MECOM^SETMOD/T=Modem no connect response 3         ');
  1877.     Set_Global_Str('ISTR_16',Parse_Str('/NC4=',G_Str));
  1878.     Set_Global_Str('IPARM_16','/C=1/L=16/W=37/H=MECOM^SETMOD/T=Modem no connect response 4         ');
  1879.  
  1880.     RM( 'USERIN^DATA_IN /A=2/#=16/S=1/T=MODEM SETUP/X=' + X_Str +
  1881.         '/Y=' + Y_Str);
  1882.  
  1883.  
  1884.     IF (Return_Int) THEN
  1885.         Changes_Made := Changes_Made or $02;
  1886.         Set_Global_Str('Com_Modem_Params','/MODEM=' +
  1887.             '/XP=' + Caps(Global_Str('ISTR_1') +
  1888.             '/XC=' + Global_Str('ISTR_2') +
  1889.             '/XT=' + Global_Str('ISTR_3') +
  1890.             '/XE=' + Global_Str('ISTR_4') +
  1891.             '/I=' + Global_Str('ISTR_5') +
  1892.             '/DC=' + Global_Str('ISTR_6') +
  1893.             '/DS=' + Global_Str('ISTR_7') +
  1894.             '/H=' + Global_Str('ISTR_8') +
  1895.             '/HM=' + Str(Global_Int('IINT_9')) +
  1896.             '/RT=' + Str(Global_Int('IINT_10')) +
  1897.             '/RP=' + Str(Global_Int('IINT_11')) +
  1898.             '/CS=' + Global_Str('ISTR_12') +
  1899.             '/NC1=' + Global_Str('ISTR_13') +
  1900.             '/NC2=' + Global_Str('ISTR_14') +
  1901.             '/NC3=' + Global_Str('ISTR_15') +
  1902.             '/NC4=' + Global_Str('ISTR_16'))
  1903.             );
  1904.     END;
  1905.     Ret;
  1906.  
  1907. SETUP_TERMINAL:
  1908.     G_Str := Global_Str('Com_Terminal_Params');
  1909.     Set_Global_Str('ISTR_1','Dumb(MECOM^SETTER)Ansi()');
  1910.     Set_Global_Int('IINT_1',((XPos(Parse_Str('/T=',
  1911.                 G_Str),'DUMB    ANSI    ',1) / 8) + 1));
  1912.     Set_Global_Str('IPARM_1','/TP=3/C=1/L=1/W=8/H=MECOM^SETTER/T=Terminal emulation           ');
  1913.     Set_Global_Str('ISTR_2','/F=Full/T=Half');
  1914.     Set_Global_Int('IINT_2',Parse_Int('/D=',G_Str));
  1915.     Set_Global_Str('IPARM_2','/TP=5/C=1/L=2/W=4/H=MECOM^SETTER/T=Duplex                       ');
  1916.     Set_Global_Str('ISTR_3','/T=Cr-Lf/F=Cr');
  1917.     Set_Global_Int('IINT_3',Parse_Int('/CI=',G_Str));
  1918.     Set_Global_Str('IPARM_3','/TP=5/C=1/L=3/W=5/H=MECOM^SETTER/T=Incoming CR=                 ');
  1919.     Set_Global_Str('ISTR_4','/T=Cr-Lf/F=Cr');
  1920.     Set_Global_Int('IINT_4',Parse_Int('/CO=',G_Str));
  1921.     Set_Global_Str('IPARM_4','/TP=5/C=1/L=4/W=5/H=MECOM^SETTER/T=Outgoing CR=                 ');
  1922.     Set_Global_Str('ISTR_5','/T=Destructive/F=Non-destructive');
  1923.     Set_Global_Int('IINT_5',Parse_Int('/BT=',G_Str));
  1924.     Set_Global_Str('IPARM_5','/TP=5/C=1/L=5/W=15/H=MECOM^SETTER/T=Backspace                    ');
  1925.     Set_Global_Int('IINT_6',Parse_Int('/BK=',G_Str));
  1926.     Set_Global_Str('IPARM_6','/TP=1/C=1/L=6/W=3/H=MECOM^SETTER/T=ASCII code of outgoing BS=   ');
  1927.     Set_Global_Str('ISTR_7','/T=On/F=Off');
  1928.     Set_Global_Int('IINT_7',Parse_Int('/W=',G_Str));
  1929.     Set_Global_Str('IPARM_7','/TP=5/C=1/L=7/W=3/H=MECOM^SETTER/T=Line wrap                    ');
  1930.     Set_Global_Int('IINT_8',Parse_Int('/BL=',G_Str));
  1931.     Set_Global_Str('IPARM_8','/TP=1/C=1/L=8/W=2/H=MECOM^SETTER/T=Break duration in clock tics=');
  1932. {This scrolling stuff is for when we get scroll defeat enabled in VP routines}
  1933.     Set_Global_Str('ISTR_9','/T=On/F=Off');
  1934.     Set_Global_Int('IINT_9',Parse_Int('/S=',G_Str));
  1935.     Set_Global_Str('IPARM_9','/TP=5/C=1/L=8/W=3/H=MECOM^SETTER/T=Scroll                        ');
  1936.     RM( 'USERIN^DATA_IN /A=2/#=8/S=1/T=TERMINAL SETUP/X=' + X_Str +
  1937.         '/Y=' + Y_Str);
  1938.  
  1939.  
  1940.     IF (Return_Int) THEN
  1941.         Changes_Made := Changes_Made or $04;
  1942.         Set_Global_Str('Com_Terminal_Params','/TERMINAL=' +
  1943.             '/T=' + Remove_Space(Copy('DUMB    ANSI    ',((Global_Int('IINT_1') - 1) * 8) + 1,8)) +
  1944.             '/D=' + Str(Global_Int('IINT_2')) +
  1945.             '/CI=' + Str(Global_Int('IINT_3')) +
  1946.             '/CO=' + Str(Global_Int('IINT_4')) +
  1947.             '/BT=' + Str(Global_Int('IINT_5')) +
  1948.             '/BK=' + Str(Global_Int('IINT_6')) +
  1949.             '/W=' + Str(Global_Int('IINT_7')) +
  1950.             '/BL=' + Str(Global_Int('IINT_8'))
  1951.             );
  1952.     END;
  1953.     Ret;
  1954.  
  1955. SETUP_PORT:
  1956.     G_Str := Global_Str('Com_Line_Params');
  1957.     Set_Global_Str( 'ISTR_1','1(MECOM^SETPOR)2()3()4()5()6()7()8()');
  1958.     Set_Global_Int( 'IINT_1',Parse_Int('/C=',G_Str));
  1959.     Set_Global_Str( 'IPARM_1','/C=11/L=1/W=1/H=MECOM^SETPOR/TP=3/T=Active com port   ');
  1960.     Set_Global_Str( 'ISTR_2',
  1961.         '110(MECOM^SETPOR)300()450()600()1200()2400()4800()9600()19200()');
  1962.     Set_Global_Int( 'IINT_2',Parse_Int('/B=',G_Str) + 1);
  1963.     Set_Global_Str( 'IPARM_2','/C=11/L=2/W=5/H=MECOM^SETPOR/TP=3/T=Baud rate         ');
  1964.     Set_Global_Str( 'ISTR_3','None(MECOM^SETPOR)Odd()Even()');
  1965.     Set_Global_Int( 'IINT_3',Parse_Int('/P=',G_Str) + 1);
  1966.     Set_Global_Str( 'IPARM_3','/C=11/L=3/W=4/H=MECOM^SETPOR/TP=3/T=Parity            ');
  1967.     Set_Global_Str( 'ISTR_4','5(MECOM^SETPOR)6()7()8()');
  1968.     Set_Global_Int( 'IINT_4',Parse_Int('/D=',G_Str) + 1);
  1969.     Set_Global_Str( 'IPARM_4','/C=11/L=4/W=1/H=MECOM^SETPOR/TP=3/T=Data bits         ');
  1970.     Set_Global_Str( 'ISTR_5','/T=2/F=1');
  1971.     Set_Global_Int( 'IINT_5',Parse_Int('/S=',G_Str));
  1972.     Set_Global_Str( 'IPARM_5','/C=11/L=5/W=1/H=MECOM^SETPOR/TP=5/T=Stop bits         ');
  1973.     Set_Global_Int('IINT_6',Parse_Int('/IB=',G_Str));
  1974.     Set_Global_Str('IPARM_6','/TP=1/C=11/L=6/W=4/H=MECOM^SETPOR/T=Input buffer size ');
  1975.     Set_Global_Int('IINT_7',Parse_Int('/OB=',G_Str));
  1976.     Set_Global_Str('IPARM_7','/TP=1/C=11/L=7/W=4/H=MECOM^SETPOR/T=Output buffer size');
  1977.     Set_Global_Str('ISTR_8','/T=On/F=Off');
  1978.     Set_Global_Int('IINT_8',Parse_Int('/XON=',G_Str));
  1979.     Set_Global_Str('IPARM_8','/TP=5/C=11/L=8/W=3/H=MECOM^SETPOR/T=Xon-Xoff          ');
  1980.     Set_Global_Str('ISTR_9','/T=On/F=Off');
  1981.     Set_Global_Int('IINT_9',Parse_Int('/CTS=',G_Str));
  1982.     Set_Global_Str('IPARM_9','/TP=5/C=11/L=9/W=3/H=MECOM^SETPOR/T=Require CTS       ');
  1983.     Set_Global_Str('ISTR_10','/T=On/F=Off');
  1984.     Set_Global_Int('IINT_10',Parse_Int('/DTR=',G_Str));
  1985.     Set_Global_Str('IPARM_10','/TP=5/C=11/L=10/W=3/H=MECOM^SETPOR/T=DTR enable        ');
  1986.     Set_Global_Str('ISTR_11','/T=On/F=Off');
  1987.     Set_Global_Int('IINT_11',Parse_Int('/RTS=',G_Str));
  1988.     Set_Global_Str('IPARM_11','/TP=5/C=11/L=11/W=3/H=MECOM^SETPOR/T=RTS enable        ');
  1989.     Set_Global_Str('ISTR_12','Setup port addresses, interrupts, and types');
  1990.     Set_Global_Str('IPARM_12','/TP=8/C=0/L=12/W=43/H=MECOM^SETPOR/T=/M=COM_SETUP_PORT');
  1991.  
  1992. {We must initialize the addresses, etc even if we aren't using them}
  1993.     RM('COM_SETUP_PORT /I=1');
  1994.  
  1995.     RM( 'USERIN^DATA_IN /A=2/#=12/S=1/T=PORT SETUP/X=' + X_Str +
  1996.         '/Y=' + Str(Menu_Y - 6));
  1997.  
  1998.     IF (Return_Int) THEN
  1999.         Jx := Parse_Int('/C=',Global_Str('Com_Line_Params'));
  2000.         Changes_Made := Changes_Made or $08;
  2001.         Set_Global_Str('Com_Line_Params','/LINE=' +
  2002.             '/C=' + Str(Global_Int('IINT_1')) +
  2003.             '/B=' + Str(Global_Int('IINT_2') - 1) +
  2004.             '/P=' + Str(Global_Int('IINT_3') - 1) +
  2005.             '/D=' + Str(Global_Int('IINT_4') - 1) +
  2006.             '/S=' + Str(Global_Int('IINT_5')) +
  2007.             '/IB=' + Str(Global_Int('IINT_6')) +
  2008.             '/OB=' + Str(Global_Int('IINT_7')) +
  2009.             '/XON=' +    Str(Global_Int('IINT_8')) +
  2010.             '/CTS=' +    Str(Global_Int('IINT_9')) +
  2011.             '/DTR=' +    Str(Global_Int('IINT_10')) +
  2012.             '/RTS=' +    Str(Global_Int('IINT_11')) +
  2013.  
  2014.             '/A1=' + Str(Global_Int('AIINT_1')) +
  2015.             '/I1=' + Str(Global_Int('AIINT_2')) +
  2016.             '/T1=' + Str(Global_Int('AIINT_3')) +
  2017.             '/A2=' + Str(Global_Int('AIINT_4')) +
  2018.             '/I2=' + Str(Global_Int('AIINT_5')) +
  2019.             '/T2=' + Str(Global_Int('AIINT_6')) +
  2020.             '/A3=' + Str(Global_Int('AIINT_7')) +
  2021.             '/I3=' + Str(Global_Int('AIINT_8')) +
  2022.             '/T3=' + Str(Global_Int('AIINT_9')) +
  2023.             '/A4=' + Str(Global_Int('AIINT_10')) +
  2024.             '/I4=' + Str(Global_Int('AIINT_11')) +
  2025.             '/T4=' + Str(Global_Int('AIINT_12')) +
  2026.             '/A5=' + Str(Global_Int('AIINT_13')) +
  2027.             '/I5=' + Str(Global_Int('AIINT_14')) +
  2028.             '/T5=' + Str(Global_Int('AIINT_15')) +
  2029.             '/A6=' + Str(Global_Int('AIINT_16')) +
  2030.             '/I6=' + Str(Global_Int('AIINT_17')) +
  2031.             '/T6=' + Str(Global_Int('AIINT_18')) +
  2032.             '/A7=' + Str(Global_Int('AIINT_19')) +
  2033.             '/I7=' + Str(Global_Int('AIINT_20')) +
  2034.             '/T7=' + Str(Global_Int('AIINT_21')) +
  2035.             '/A8=' + Str(Global_Int('AIINT_22')) +
  2036.             '/I8=' + Str(Global_Int('AIINT_23')) +
  2037.             '/T8=' + Str(Global_Int('AIINT_24'))
  2038.         );
  2039.  
  2040.         Set_Global_Str('Com_Cur_Line_Params',
  2041.             '/C=' + Str(Global_Int('IINT_1')) +
  2042.             '/B=' + Str(Global_Int('IINT_2') - 1) +
  2043.             '/P=' + Str(Global_Int('IINT_3') - 1) +
  2044.             '/D=' + Str(Global_Int('IINT_4') - 1) +
  2045.             '/S=' + Str(Global_Int('IINT_5'))
  2046.         );
  2047.         RM('MECOM^COM_OPEN_PORT /P=' + Str(Jx));
  2048.  
  2049.     END;
  2050.  
  2051.     RET;
  2052.  
  2053. SETUP_SCREEN:
  2054.     Sub_Choice := 1;
  2055.     B_Str := '';
  2056.  
  2057. SCREEN_MENU:
  2058.     Create_Global_Str('COMSCREENSTR_1','/H=MECOM^SETSCRCOL');
  2059.     Create_Global_Str('XCOMSCREENSTR_1','Colors');
  2060.     Create_Global_Str('COMSCREENSTR_2','/H=MECOM^SETSCRBOX');
  2061.     Create_Global_Str('XCOMSCREENSTR_2','Box size');
  2062.     Create_Global_Str('COMSCREENSTR_3','/H=MECOM^SETSCRSCR');
  2063.     Create_Global_Str('XCOMSCREENSTR_3','Full screen ^' + Copy('OffOn ',
  2064.         (Parse_Int('/FS=',Global_Str('Com_Screen_Params')) * 3) + 1,3));
  2065.     Create_Global_Str('COMSCREENSTR_4','/H=MECOM^SETSCRSTA');
  2066.     Create_Global_Str('XCOMSCREENSTR_4','Status line ^' + Copy('Top   Bottom',
  2067.         (Parse_Int('/SR=',Global_Str('Com_Screen_Params')) * 6) + 1,6));
  2068.  
  2069.     RM('USERIN^SUBMENU /M=XCOMSCREENSTR_/G=COMSCREENSTR_/#=4/L=SETUP SCREEN/S=' +
  2070.         Str(Sub_Choice) + '/X=' + X_Str + '/GCLR=1/Y=' + Str(Menu_Y - 3) + B_Str);
  2071.     Sub_Choice := Return_Int;
  2072.     IF (Sub_Choice > 0) THEN
  2073.         B_Str := '/B=1/BO=1';
  2074.         IF (Sub_Choice = 1) THEN
  2075. COLOR_MENU:
  2076.             Menu_X := 4;
  2077.             T_Fore := Parse_Int('/F=',Global_Str('Com_Color_Params'));
  2078.             T_Back := Parse_Int('/B=',Global_Str('Com_Color_Params'));
  2079. {Create the menu with box}
  2080.             Put_Box(Menu_X,Menu_Y - 1,Menu_X + 34,Menu_Y + 4,0,M_B_Color,'COLORS',true);
  2081.  
  2082. COLOR_LOOP:
  2083.             write(' to change foreground color  ',Menu_X + 1,Menu_Y,0,(T_Back shl 4) or (T_Fore and $0F));
  2084.             write('|27|26 to change background color. ',Menu_X + 1,Menu_Y + 1,0,(T_Back shl 4) or (T_Fore and $0F));
  2085.             write('<ENTER> to accept, <ESC> aborts',Menu_X + 1,Menu_Y + 2,0,(T_Back shl 4) or (T_Fore and $0F));
  2086.  
  2087.             Read_Key;
  2088.             Jx := Inq_Key(Key1,Key2,TERM,MStr);
  2089.             IF ((Jx = 1) and (MStr = 'MECOM^COM_HELP')) THEN
  2090.                 Help('MECOM^SETSCRCOL');
  2091.             END;
  2092.             IF (Key1 = 27) THEN
  2093.                 Goto COLOR_EXIT;
  2094.             END;
  2095.             IF (Key1 = 13) THEN
  2096.                 Text_Color_Vp := T_Fore or (T_Back shl 4);
  2097.                 Set_Global_Str('Com_Color_Params','/COLOR=' +
  2098.                     '/F=' + Str(T_Fore and $0F) +
  2099.                     '/B=' + Str(T_Back and $0F)
  2100.                     );
  2101.                 Goto COLOR_EXIT;
  2102.             END;
  2103.             IF (Key1 = 0) THEN
  2104.                 IF (Key2 = 72) THEN
  2105.                     Changes_Made := Changes_Made or $10;
  2106.                     --T_Fore;
  2107.                 END;
  2108.                 IF (Key2 = 80) THEN
  2109.                     Changes_Made := Changes_Made or $10;
  2110.                     ++T_Fore;
  2111.                 END;
  2112.                 IF (Key2 = 75) THEN
  2113.                     Changes_Made := Changes_Made or $10;
  2114.                     --T_Back;
  2115.                 END;
  2116.                 IF (Key2 = 77) THEN
  2117.                     Changes_Made := Changes_Made or $10;
  2118.                     ++T_Back;
  2119.                 END;
  2120.             END;
  2121.             Goto Color_LOOP;
  2122.  
  2123. COLOR_EXIT:
  2124.             Kill_Box;
  2125.         END;
  2126.         IF (Sub_Choice = 2) THEN
  2127.             Message_Row := 1;
  2128.             Save_Box(1,1,80,Screen_Length);
  2129.             G_Str := Global_Str('Com_Box_Params');
  2130.             RM('WINDOW^MOVE_WIN /K=1/MX1=0/MY1=' + Parse_Str('/SR=',Global_Str('Com_Screen_Params')) +
  2131.             '/MX2=' + Str(Screen_Width + 1) +
  2132.                 '/MY2=' + Str(Screen_Length - 1 + Parse_Int('/SR=',Global_Str('Com_Screen_Params'))) +
  2133.                 '/X1=' + Parse_Str('/X1=',G_Str) +
  2134.                 '/Y1=' + Parse_Str('/Y1=',G_Str) +
  2135.                 '/X2=' + Parse_Str('/X2=',G_Str) +
  2136.                 '/Y2=' + Parse_Str('/Y2=',G_Str));
  2137.             Kill_Box;
  2138.             IF (Return_Int) THEN
  2139.                 Changes_Made := Changes_Made or $10;
  2140.                 Set_Global_Str('Com_Box_Params','/BOX=' +
  2141.                     '/X1=' + Parse_Str('/X1=',Return_Str) +
  2142.                     '/Y1=' + Parse_Str('/Y1=',Return_Str) +
  2143.                     '/X2=' + Parse_Str('/X2=',Return_Str) +
  2144.                     '/Y2=' + Parse_Str('/Y2=',Return_Str)
  2145.                     );
  2146.             END;
  2147.             Message_Row := 0;
  2148.         END;
  2149.         IF (Sub_Choice = 3) THEN
  2150.             Set_Global_Str('Com_Screen_Params','/SCREEN=/FS=' +
  2151.                 Str(Not(Parse_Int('/FS=',Global_Str('Com_Screen_Params')))) +
  2152.                 '/SR=' + Parse_Str('/SR=',Global_Str('Com_Screen_Params'))
  2153.                 );
  2154.             Changes_Made := Changes_Made or $10;
  2155.         END;
  2156.         IF (Sub_Choice = 4) THEN
  2157.             Set_Global_Str('Com_Screen_Params','/SCREEN=/FS=' +
  2158.                 Parse_Str('/FS=',Global_Str('Com_Screen_Params')) +
  2159.                 '/SR=' + Str(Not(Parse_Int('/SR=',Global_Str('Com_Screen_Params'))))
  2160.                 );
  2161.             Changes_Made := Changes_Made or $10;
  2162.         END;
  2163.         Goto SCREEN_MENU;
  2164.     END;
  2165.     IF (B_Str <> '') THEN
  2166.         Kill_Box;
  2167.     END;
  2168.  
  2169.     RET;
  2170.  
  2171. SETUP_PROTOCOL:
  2172.     Sub_Choice := Type - 6;
  2173.     RM('MECOM^COM_PROTO_MENU /LO=0/X=3/Y=' + Str(Menu_Y - 4 + Sub_Choice) + '/DU=' + Str(Sub_Choice));
  2174.     RET;
  2175.  
  2176. SETUP_ASCII:
  2177.     G_Str := Global_Str('Com_Ascii_Params');
  2178.     Set_Global_Str('ISTR_1','/T=On/F=Off');
  2179.     Set_Global_Int('IINT_1',Parse_Int('/E=',G_Str));
  2180.     Set_Global_Str('IPARM_1','/TP=5/C=1/L=1/W=3/H=MECOM^SETASC/T=Local echo                        ');
  2181.     Set_Global_Str('ISTR_2','/T=On/F=Off');
  2182.     Set_Global_Int('IINT_2',Parse_Int('/S=',G_Str));
  2183.     Set_Global_Str('IPARM_2','/TP=5/C=1/L=2/W=3/H=MECOM^SETASC/T=Add space character to blank lines');
  2184.     Set_Global_Int('IINT_3',Parse_Int('/PC=',G_Str));
  2185.     Set_Global_Str('IPARM_3','/TP=1/C=1/L=3/W=3/H=MECOM^SETASC/T=ASCII code of pace character      ');
  2186.     Set_Global_Int('IINT_4',Parse_Int('/CP=',G_Str));
  2187.     Set_Global_Str('IPARM_4','/TP=1/C=1/L=4/W=2/H=MECOM^SETASC/T=Character pacing(in milliseconds) ');
  2188.     Set_Global_Int('IINT_5',Parse_Int('/LP=',G_Str));
  2189.     Set_Global_Str('IPARM_5','/TP=1/C=1/L=5/W=2/H=MECOM^SETASC/T=Line pacing(in 100ths of a second)');
  2190.     Set_Global_Str('ISTR_6','Cr(MECOM^SETASC)cr-Lf()Strip()');
  2191.     Set_Global_Int('IINT_6',Parse_Int('/CU=',G_Str) + 1);
  2192.     Set_Global_Str('IPARM_6','/TP=3/C=1/L=6/W=5/H=MECOM^SETASC/T=Upload CR=                        ');
  2193.     Set_Global_Str('ISTR_7','Lf(MECOM^SETASC)Cr-lf()Strip()');
  2194.     Set_Global_Int('IINT_7',Parse_Int('/LU=',G_Str) + 1);
  2195.     Set_Global_Str('IPARM_7','/TP=3/C=1/L=7/W=5/H=MECOM^SETASC/T=Upload LF=                        ');
  2196.     Set_Global_Str('ISTR_8','Cr(MECOM^SETASC)cr-Lf()Strip()');
  2197.     Set_Global_Int('IINT_8',Parse_Int('/CD=',G_Str) + 1);
  2198.     Set_Global_Str('IPARM_8','/TP=3/C=1/L=8/W=5/H=MECOM^SETASC/T=Download CR=                      ');
  2199.     Set_Global_Str('ISTR_9','Lf(MECOM^SETASC)Cr-lf()Strip()');
  2200.     Set_Global_Int('IINT_9',Parse_Int('/LD=',G_Str) + 1);
  2201.     Set_Global_Str('IPARM_9','/TP=3/C=1/L=9/W=5/H=MECOM^SETASC/T=Download LF=                      ');
  2202.  
  2203.     RM( 'USERIN^DATA_IN /A=2/#=9/S=1/T=ASCII TRANSFER SETUP/X=' + X_Str +
  2204.         '/Y=' + Y_Str);
  2205.  
  2206.  
  2207.     IF (Return_Int) THEN
  2208.         Changes_Made := Changes_Made or $20;
  2209.         Set_Global_Str('Com_Ascii_Params','/ASCII=' +
  2210.             '/E=' + Str(Global_Int('IINT_1')) +
  2211.             '/S=' + Str(Global_Int('IINT_2')) +
  2212.             '/PC=' + Str(Global_Int('IINT_3')) +
  2213.             '/CP=' + Str(Global_Int('IINT_4')) +
  2214.             '/LP=' + Str(Global_Int('IINT_5')) +
  2215.             '/CU=' + Str(Global_Int('IINT_6') - 1) +
  2216.             '/LU=' + Str(Global_Int('IINT_7') - 1) +
  2217.             '/CD=' + Str(Global_Int('IINT_8') - 1) +
  2218.             '/LD=' + Str(Global_Int('IINT_9') - 1)
  2219.             );
  2220.     END;
  2221.     RET;
  2222.  
  2223. SAVE_SETUP:
  2224.     IF (Switch_Win_Id(Global_Int('Com_Init_Window'))) THEN
  2225.         Tof;
  2226.  
  2227.         G_Str := 'General';
  2228.         Call UPDATE_LINE;
  2229.  
  2230.         G_Str := 'Box';
  2231.         Call UPDATE_LINE;
  2232.  
  2233.         G_Str := 'Color';
  2234.         Call UPDATE_LINE;
  2235.  
  2236.         G_Str := 'Screen';
  2237.         Call UPDATE_LINE;
  2238.  
  2239.         G_Str := 'Modem';
  2240.         Call UPDATE_LINE;
  2241.  
  2242.         G_Str := 'Terminal';
  2243.         Call UPDATE_LINE;
  2244.  
  2245.         G_Str := 'Line';
  2246.         Call UPDATE_LINE;
  2247.  
  2248.         G_Str := 'ASCII';
  2249.         Call UPDATE_LINE;
  2250.         Save_File;
  2251.     END;
  2252.     Update_Status_Line;
  2253.     RET;
  2254.  
  2255. UPDATE_LINE:
  2256.     Goto_Line(Start_Line);
  2257.     IF (Search_Fwd('/' + G_Str + '=',Search_Amount) =    False) THEN
  2258.         Eol;
  2259.         ++Search_Amount;
  2260.         Insert_Mode := True;
  2261.         Cr;
  2262.     END;
  2263.     Put_Line(Global_Str('COM_' + G_Str + '_PARAMS'));
  2264.     RET;
  2265.  
  2266. {*****************************************************************************}
  2267.  
  2268. EXIT:
  2269.     Set_Global_Int('COM_CHANGES_MADE',Changes_Made);
  2270.     IF (Type = 10) THEN
  2271.         Return_Int := 100;
  2272.     ELSE
  2273.         Return_Int := 0;
  2274.     END;
  2275. {Deallocate global variables used for DATA_IN and SUBMENU}
  2276.     Jx := 0;
  2277.  
  2278.     WHILE (Jx < 33) DO
  2279.         Set_Global_Str( 'ISTR_' + Str(Jx),'');
  2280.         Set_Global_Int( 'IINT_' + Str(Jx),0);
  2281.         Set_Global_Str( 'IPARM_' + Str(Jx),'');
  2282.         ++Jx;
  2283.     END;
  2284.     Jx := 0;
  2285.  
  2286.     WHILE (Jx < 24) DO
  2287.         Set_Global_Str( 'ISTRA_' + Str(Jx),'');
  2288.         Set_Global_Int( 'IINTA_' + Str(Jx),0);
  2289.         Set_Global_Str( 'IPARMA_' + Str(Jx),'');
  2290.         ++Jx;
  2291.     END;
  2292.     Jx := 1;
  2293.     WHILE (Jx < 4) DO
  2294.             Set_Global_Str('COMSCREENSTR_' + Str(Jx),'');
  2295.             Set_Global_Str('XCOMSCREENSTR_' + Str(Jx),'');
  2296.         ++Jx;
  2297.     END;
  2298. END_MACRO;
  2299.  
  2300.  
  2301. $MACRO COM_SETUP_PORT;
  2302. {*******************************MULTI-EDIT MACRO*******************************
  2303.  
  2304. Name:    COM_SETUP_PORT
  2305.  
  2306. Description:    This macro is the port address, interrupt, and type menu called
  2307. from COM_SETUP.  This macro is not intended to be called from anything but
  2308. COM_SETUP.
  2309.  
  2310. Parameters:
  2311.                             /I= If 1, initialize the globals only, don't show the menu.
  2312.                             /X=, /Y=  The upper left hand X and Y coordinates.
  2313.  
  2314.                              (C) Copyright 1990 by American Cybernetics, Inc.
  2315. ******************************************************************************}
  2316.     Def_Int(Menu_X,Menu_Y);
  2317.     Menu_X := Parse_Int('/X=',MParm_Str);
  2318.     Menu_Y := Parse_Int('/Y=',MParm_Str);
  2319.     Return_Str := Global_Str('Com_Line_Params');
  2320.     Set_Global_Int('AIINT_1',Parse_Int('/A1=',Return_Str));
  2321.     Set_Global_Str('AIPARM_1','/TP=4/C=1/L=1/W=4/H=MECOM^SETPOR/T=COM1 address');
  2322.     Set_Global_Int('AIINT_2',Parse_Int('/I1=',Return_Str));
  2323.     Set_Global_Str('AIPARM_2','/TP=1/C=20/L=1/W=3/H=MECOM^SETPOR/T=COM1 interrupt');
  2324.     Set_Global_Str('AISTR_3','/T=Modem/F=Direct');
  2325.     Set_Global_Int('AIINT_3',Parse_Int('/T1=',Return_Str));
  2326.     Set_Global_Str('AIPARM_3','/TP=5/C=39/L=1/W=6/H=MECOM^SETPOR/T=COM1 connection');
  2327.     Set_Global_Int('AIINT_4',Parse_Int('/A2=',Return_Str));
  2328.     Set_Global_Str('AIPARM_4','/TP=4/C=1/L=2/W=4/H=MECOM^SETPOR/T=COM2 address');
  2329.     Set_Global_Int('AIINT_5',Parse_Int('/I2=',Return_Str));
  2330.     Set_Global_Str('AIPARM_5','/TP=1/C=20/L=2/W=3/H=MECOM^SETPOR/T=COM2 interrupt');
  2331.     Set_Global_Str('AISTR_6','/T=Modem/F=Direct');
  2332.     Set_Global_Int('AIINT_6',Parse_Int('/T2=',Return_Str));
  2333.     Set_Global_Str('AIPARM_6','/TP=5/C=39/L=2/W=6/H=MECOM^SETPOR/T=COM2 connection');
  2334.     Set_Global_Int('AIINT_7',Parse_Int('/A3=',Return_Str));
  2335.     Set_Global_Str('AIPARM_7','/TP=4/C=1/L=3/W=4/H=MECOM^SETPOR/T=COM3 address');
  2336.     Set_Global_Int('AIINT_8',Parse_Int('/I3=',Return_Str));
  2337.     Set_Global_Str('AIPARM_8','/TP=1/C=20/L=3/W=3/H=MECOM^SETPOR/T=COM3 interrupt');
  2338.     Set_Global_Str('AISTR_9','/T=Modem/F=Direct');
  2339.     Set_Global_Int('AIINT_9',Parse_Int('/T3=',Return_Str));
  2340.     Set_Global_Str('AIPARM_9','/TP=5/C=39/L=3/W=6/H=MECOM^SETPOR/T=COM3 connection');
  2341.     Set_Global_Int('AIINT_10',Parse_Int('/A4=',Return_Str));
  2342.     Set_Global_Str('AIPARM_10','/TP=4/C=1/L=4/W=4/H=MECOM^SETPOR/T=COM4 address');
  2343.     Set_Global_Int('AIINT_11',Parse_Int('/I4=',Return_Str));
  2344.     Set_Global_Str('AIPARM_11','/TP=1/C=20/L=4/W=3/H=MECOM^SETPOR/T=COM4 interrupt');
  2345.     Set_Global_Str('AISTR_12','/T=Modem/F=Direct');
  2346.     Set_Global_Int('AIINT_12',Parse_Int('/T4=',Return_Str));
  2347.     Set_Global_Str('AIPARM_12','/TP=5/C=39/L=4/W=6/H=MECOM^SETPOR/T=COM4 connection');
  2348.     Set_Global_Int('AIINT_13',Parse_Int('/A5=',Return_Str));
  2349.     Set_Global_Str('AIPARM_13','/TP=4/C=1/L=5/W=4/H=MECOM^SETPOR/T=COM5 address');
  2350.     Set_Global_Int('AIINT_14',Parse_Int('/I5=',Return_Str));
  2351.     Set_Global_Str('AIPARM_14','/TP=1/C=20/L=5/W=3/H=MECOM^SETPOR/T=COM5 interrupt');
  2352.     Set_Global_Str('AISTR_15','/T=Modem/F=Direct');
  2353.     Set_Global_Int('AIINT_15',Parse_Int('/T5=',Return_Str));
  2354.     Set_Global_Str('AIPARM_15','/TP=5/C=39/L=5/W=6/H=MECOM^SETPOR/T=COM5 connection');
  2355.     Set_Global_Int('AIINT_16',Parse_Int('/A6=',Return_Str));
  2356.     Set_Global_Str('AIPARM_16','/TP=4/C=1/L=6/W=4/H=MECOM^SETPOR/T=COM6 address');
  2357.     Set_Global_Int('AIINT_17',Parse_Int('/I6=',Return_Str));
  2358.     Set_Global_Str('AIPARM_17','/TP=1/C=20/L=6/W=3/H=MECOM^SETPOR/T=COM6 interrupt');
  2359.     Set_Global_Str('AISTR_18','/T=Modem/F=Direct');
  2360.     Set_Global_Int('AIINT_18',Parse_Int('/T6=',Return_Str));
  2361.     Set_Global_Str('AIPARM_18','/TP=5/C=39/L=6/W=6/H=MECOM^SETPOR/T=COM6 connection');
  2362.     Set_Global_Int('AIINT_19',Parse_Int('/A7=',Return_Str));
  2363.     Set_Global_Str('AIPARM_19','/TP=4/C=1/L=7/W=4/H=MECOM^SETPOR/T=COM7 address');
  2364.     Set_Global_Int('AIINT_20',Parse_Int('/I7=',Return_Str));
  2365.     Set_Global_Str('AIPARM_20','/TP=1/C=20/L=7/W=3/H=MECOM^SETPOR/T=COM7 interrupt');
  2366.     Set_Global_Str('AISTR_21','/T=Modem/F=Direct');
  2367.     Set_Global_Int('AIINT_21',Parse_Int('/T7=',Return_Str));
  2368.     Set_Global_Str('AIPARM_21','/TP=5/C=39/L=7/W=6/H=MECOM^SETPOR/T=COM7 connection');
  2369.     Set_Global_Int('AIINT_22',Parse_Int('/A8=',Return_Str));
  2370.     Set_Global_Str('AIPARM_22','/TP=4/C=1/L=8/W=4/H=MECOM^SETPOR/T=COM8 address');
  2371.     Set_Global_Int('AIINT_23',Parse_Int('/I8=',Return_Str));
  2372.     Set_Global_Str('AIPARM_23','/TP=1/C=20/L=8/W=3/H=MECOM^SETPOR/T=COM8 interrupt');
  2373.     Set_Global_Str('AISTR_24','/T=Modem/F=Direct');
  2374.     Set_Global_Int('AIINT_24',Parse_Int('/T7=',Return_Str));
  2375.     Set_Global_Str('AIPARM_24','/TP=5/C=39/L=8/W=6/H=MECOM^SETPOR/T=COM8 connection');
  2376. {If we simply want to initialize the globals, then don't do the DATA_IN}
  2377.     IF (Parse_Int('/I=',MParm_Str)) THEN
  2378.         Goto EXIT;
  2379.     END;
  2380.  
  2381.     RM('DATA_IN /PRE=A/A=2/#=24/S=1/T=PORT SETUP/X=' + Str(Menu_X + 1) +
  2382.         '/Y=' + Str(Menu_Y + 1));
  2383. EXIT:
  2384.     Return_Str := 'Setup port addresses, interrupts, and types';
  2385. END_MACRO;
  2386.  
  2387. $MACRO COM_PHONE TRANS;
  2388. {*******************************MULTI-EDIT MACRO*******************************
  2389.  
  2390. Name:    COM_PHONE
  2391.  
  2392. Description:    The comunications module phone dialing and hang up macro.
  2393.  
  2394. Parameters:
  2395.                             /MY= The Y coordinate reference point for making boxes.
  2396.                             /TP=
  2397.                                         1   autodial menu
  2398.                                         2   manual dial menu
  2399.                                         3   hangup
  2400.                                         4   redial menu
  2401.  
  2402. Returns:
  2403.                             Return_Int (only meaningful for redial)
  2404.                                 1 = successful
  2405.                                 0 = not successful
  2406.  
  2407.                              (C) Copyright 1990 by American Cybernetics, Inc.
  2408. ******************************************************************************}
  2409. {
  2410. This macro is the phone menu including the phone dialing list for the
  2411. communications module
  2412. /N=/#=/B=/P=/D=/S=/E=/M=
  2413. Parameters:
  2414. /TP=    1   Go directly to autodial menu
  2415. /TP=    2   Go directly to manual dial menu
  2416. /TP=    3   Go directly to hangup
  2417. /TP=    4   Go directly to redial menu
  2418. }
  2419.     Def_Int(Active_Window,DIAL_Window,Jx,Jy,Temp_Reg_Exp_Stat,Temp_Integer,
  2420.                     Menu_Index,Temp_Insert_Mode,Menu_Choice,Error,Port_Num,Redial_Count,
  2421.                     Menu_Y,Type,Response_Length,Terminator_Index,T_Start,T_Stop);
  2422.     Def_Str(Temp_Char);
  2423.     Def_Str(Temp_String,Modem_Response,Macro,Terminator_Chars,MStr);
  2424.  
  2425.     port_num := global_int('COM_PORT_NUM');
  2426.  
  2427. {determine how much is the longest expected connect/no connect modem response}
  2428.     Response_Length := Length(Parse_Str('/CS=',Global_Str('Com_Modem_Params')));
  2429.     Jx := 0;
  2430.     WHILE (Jx < 5) DO
  2431.         ++Jx;
  2432.         Temp_Integer := Length(Parse_Str('/NC' + Str(Jx) + '=',Global_Str('Com_Modem_Params')));
  2433.         IF (Temp_Integer > Response_Length) THEN
  2434.             Response_Length := Temp_Integer;
  2435.         END;
  2436.     END;
  2437.  
  2438.     IF (Response_Length = 0) THEN
  2439.         Response_Length := 10;
  2440.     END;
  2441.     Macro := '';
  2442.     Menu_Y := Parse_Int('/MY=',MParm_Str);
  2443.     IF (Menu_Y = 0) THEN
  2444.         Menu_Y := 2;
  2445.     END;
  2446.     Menu_Index := 0;
  2447.     DIAL_Window := 0;
  2448.     Temp_Reg_Exp_Stat := Reg_Exp_Stat;
  2449.     Reg_Exp_Stat := False;
  2450.     Temp_Insert_Mode := Insert_Mode;
  2451.     Insert_Mode := True;
  2452.     Active_Window := Cur_Window;
  2453. {Look for special parameters}
  2454.     Type := Parse_Int('/TP=',MParm_Str);
  2455.     IF (Type = 1) THEN
  2456.         Goto AUTODIAL;
  2457.     END;
  2458.     IF (Type = 2) THEN
  2459.         Goto MANUALDIAL;
  2460.     END;
  2461.     IF (Type = 3) THEN
  2462.         Return_Int := True;
  2463.         Call HANG_UP;
  2464.         Goto EXIT;
  2465.     END;
  2466.     IF (Type = 4) THEN
  2467.         Goto DO_REDIAL;
  2468.     END;
  2469.  
  2470. Goto EXIT;
  2471.  
  2472.     IF (Menu_Choice = 1) THEN
  2473. {Auto dial menu}
  2474. AUTODIAL:
  2475.         Set_Global_Str('PHONDS','N=28#=14');
  2476.         RM('USERIN^DB /F=MECOM.DB/GLO=PHONE/LO=2/PRE=PHON/NOALPHA=1/ENC=0/DPT=' +
  2477.             'PHONELST.DB/NDF=1/LT=Autodial Directory.  <ENTER> to dial./X=9/Y=' +
  2478.             Str(Menu_Y + 4) + '/DT=AUTODIAL SETUP/H=MECOM^PHONAUT/DS=PHONDS/2TOP=1');
  2479.         IF (RETURN_INT) THEN
  2480.             MStr := Global_Str('PHONE');
  2481.             Temp_String := Parse_Str('#=',MStr);
  2482.             Macro := Parse_Str('M=',MStr);
  2483.             if (Temp_String <> '') then
  2484. {Set up the com port to the setttings in the phone list}
  2485.                 Jx := Parse_Int('B=',Mstr);
  2486.                 IF (Jx > 0) THEN
  2487.                     --Jx;
  2488.                 END;
  2489.                 Jy := Parse_Int('P=',Mstr);
  2490.                 IF (Jy > 0) THEN
  2491.                     --Jy;
  2492.                 END;
  2493.                 Temp_Integer := Parse_Int('D=',Mstr);
  2494.                 IF (Temp_Integer > 0) THEN
  2495.                     --Temp_Integer;
  2496.                 END;
  2497.  
  2498.                 Terminator_Chars := '/B=' + Str(Jx) + '/P=' + Str(Jy) +
  2499.                     '/D=' + Str(Temp_Integer) + '/S=' + Str(Parse_Int('S=',MStr));
  2500.  
  2501.                 Set_Global_Str('Com_Cur_Line_Params',
  2502.                     '/C=' + Parse_Str('/C=',Global_Str('Com_Cur_Line_Params')) +
  2503.                     Terminator_Chars);
  2504.  
  2505.                 error := set_com( port_num, 1,Parse_Int('/B=',Terminator_Chars));
  2506.                 error := set_com( port_num, 2,Parse_Int('/P=',Terminator_Chars));
  2507.                 error := set_com( port_num, 3,Parse_Int('/D=',Terminator_Chars));
  2508.                 error := set_com( port_num, 4,Parse_Int('/S=',Terminator_Chars));
  2509.  
  2510. MANUAL_DIAL:
  2511.                 Return_Str := Parse_Str('/DC=',Global_Str('Com_Modem_Params')) + Temp_String;
  2512.                 Call WRITE_TO_PORT;
  2513.                 Return_Str := Parse_Str('/DS=',Global_Str('Com_Modem_Params'));
  2514.                 Call WRITE_TO_PORT;
  2515.                 Set_Global_Str('Com_Last_Dialed_#',Temp_String);
  2516.                 Set_Global_Str('Com_Last_Dialed_Macro',Macro);
  2517.                 IF (Type = 1) THEN
  2518.                     Set_Global_Int('COM_CHANGES_MADE',Global_Int('COM_CHANGES_MADE') or $08);
  2519.                     Return_Str := '/WRITE=Dialing ' + Parse_Str('N=',Global_Str('PHONE')) +
  2520.                         '|13|10';
  2521.                 ELSE
  2522.                     Return_Str := '';
  2523.                 END;
  2524.                 IF (Macro <> '') THEN
  2525.                     Return_Str := Return_Str + '/PM=' + Macro;
  2526.                 END;
  2527.             end;
  2528.             Goto EXIT;
  2529.         ELSE
  2530.             Goto ESCAPE_EXIT;
  2531.         END;
  2532.     END;
  2533.  
  2534.     IF (Menu_Choice = 2) THEN
  2535. MANUALDIAL:
  2536. {Manual dialing}
  2537.         Return_Str := '';
  2538.  
  2539.         RM('USERIN^QUERYBOX /C=9/W=40/H=MECOM^PHONMAN/P=Number to dial:/T=MANUAL DIALING/L=' + Str(Menu_Y + 5));
  2540.         IF ((Return_Int <> 0) and (Return_Str <> '')) THEN
  2541.             Temp_String := Return_Str;
  2542.             Macro := '';
  2543.             Goto MANUAL_DIAL;
  2544.         END;
  2545.         Goto ESCAPE_EXIT;
  2546.     END;
  2547.  
  2548.     IF (Menu_Choice = 3) THEN
  2549. {Hang up the phone}
  2550.         Return_Int := False;
  2551.         Call HANG_UP;
  2552.         Goto ESCAPE_EXIT;
  2553.     END;
  2554.  
  2555.     IF (Menu_Choice = 4) THEN
  2556. {redial }
  2557. DO_REDIAL:
  2558.         Redial_Count := 0;
  2559.         IF (Global_Str('Com_Last_Dialed_#') = '') THEN
  2560.             Return_Str := '';
  2561.             RM('USERIN^QUERYBOX /C=9/W=40/P=Number to dial:/T=REDIAL/L=' + Str(Menu_Y + 7));
  2562.             IF (Return_Int) THEN
  2563.                 Set_Global_Str('Com_Last_Dialed_#',Return_Str);
  2564.                 Set_Global_Str('Com_Last_Dialed_Macro','');
  2565.             ELSE
  2566.                 Goto ESCAPE_EXIT;
  2567.             END;
  2568.         END;
  2569.         Put_Box(9,Menu_Y + 7,60,Menu_Y + 14,0,M_B_Color,'AUTOMATIC REDIAL',True);
  2570.         Write('<F2>=change parameters.  <ESC>=abort.',13,Menu_Y + 13,0,M_S_Color);
  2571.         Redial_Count := 0;
  2572.  
  2573. REDIAL_CHANGE:
  2574.         Write('Number: ' + Global_Str('Com_Last_Dialed_#'),10,Menu_Y + 8,0,M_S_Color);
  2575.         Write('Number of tries: 0',10,Menu_Y + 9,0,M_S_Color);
  2576.         Write('Elapsed time: 0' +  '  seconds of: '  + Parse_Str('/RT=',
  2577.             Global_Str('Com_Modem_Params')) + ' ',10,Menu_Y + 10,0,M_S_Color);
  2578.         Write('Delay before redial time: 0' +  '  seconds of: '  + Parse_Str('/RP=',
  2579.             Global_Str('Com_Modem_Params')),10,Menu_Y + 11,0,M_S_Color);
  2580.         Write('Last modem response: ',10,Menu_Y + 12,0,M_S_Color);
  2581.  
  2582. REDIAL:
  2583.         Write('0 ',24,Menu_Y + 10,0,M_S_Color);
  2584.         Write(Str(Redial_Count),27,Menu_Y + 9,0,M_S_Color);
  2585.         Return_Str := Parse_Str('/DC=',Global_Str('Com_Modem_Params')) +
  2586.             Global_Str('Com_Last_Dialed_#');
  2587.         Call WRITE_TO_PORT;
  2588.         Return_Str := Parse_Str('/DS=',Global_Str('Com_Modem_Params'));
  2589.         Call WRITE_TO_PORT;
  2590. {This is just to clear the incoming port buffer}
  2591.         Delay(100);
  2592.         Terminator_Chars := '';
  2593.         Return_Int := 255;
  2594.         Call GET_MODEM_RESPONSE;
  2595.         Temp_Integer := Val(T_Start,Copy(Time,7,2));
  2596.  
  2597. TIMEOUT_LOOP:
  2598.         Temp_Integer := Val(T_Stop,Copy(Time,7,2));
  2599.         IF (T_Start > T_Stop) THEN
  2600.             T_Stop := T_Stop + 60;
  2601.         END;
  2602.         IF (read_com_till(port_num,1,'',Temp_Char,
  2603.             Terminator_Index) = 0) Then
  2604.             Return_Int := Response_Length;
  2605.             Terminator_Chars := '';
  2606.             Delay(500);
  2607.             Call GET_MODEM_RESPONSE;
  2608.  
  2609.             Temp_Integer := XPos(Parse_Str('/CS=',Global_Str('Com_Modem_Params')),
  2610.                 Modem_Response,1);
  2611.  
  2612.             IF (Temp_Integer) THEN
  2613. {Save any remaining stuff after the connect response into a global so that it
  2614. can be dealt with later if needed.}
  2615.                 Set_Global_Str('Com_Leftovers',Copy(Modem_Response,Temp_Integer +
  2616.                     Length(Parse_Str('/CS=',Global_Str('Com_Modem_Params'))) + 2,255));
  2617.                 Return_Int := True;
  2618.                 Kill_Box;
  2619.                 IF (Global_Str('Com_Last_Dialed_Macro') <> '') THEN
  2620.                     Return_Str := '/PM=' + Global_Str('Com_Last_Dialed_Macro');
  2621. {We are adding a special parameter "/AC=" to the macro command to indicate to
  2622. the macro that we are Already Connected.  If there are already parameters in
  2623. this macro command, we will not put in the space delimter.}
  2624.                     IF (XPos(' ',Return_Str,1) = 0) THEN
  2625.                         Return_Str := Return_Str + ' ';
  2626.                     END;
  2627.                     Return_Str := Return_Str + '/AC=1';
  2628.                 END;
  2629.                 Goto EXIT;
  2630.             ELSE
  2631. {Check if it is any of the defined modem no connect responses}
  2632.                 Jx := 1;
  2633. CHECK_NO_CONNECT:
  2634.                 Return_Str := Parse_Str('/NC' + Str(Jx) + '=',Global_Str('Com_Modem_Params'));
  2635.                 IF (Return_Str <> '') THEN
  2636.                     Temp_Integer := XPos(Return_Str,Modem_Response,1);
  2637.                     IF ((Temp_Integer = 0) and (Jx < 4)) THEN
  2638.                         ++Jx;
  2639.                         Goto CHECK_NO_CONNECT;
  2640.                     END;
  2641.                 END;
  2642. {Clean up the modem response so it can be displayed}
  2643. {Remove any CR or LF}
  2644. REMOVE_CR:
  2645.                 Jx := XPos('|13',Modem_Response,1);
  2646.                 IF (Jx) THEN
  2647.                     Modem_Response := Str_Del(Modem_Response,Jx,1);
  2648.                     Goto REMOVE_CR;
  2649.                 END;
  2650. REMOVE_LF:
  2651.                 Jx := XPos('|10',Modem_Response,1);
  2652.                 IF (Jx) THEN
  2653.                     Modem_Response := Str_Del(Modem_Response,Jx,1);
  2654.                     Goto REMOVE_LF;
  2655.                 END;
  2656.                 Modem_Response := Copy(Modem_Response + '                              ',1,22);
  2657. {If we got one of the no connect modem responses, then hang up, otherwise
  2658. display, but ignore the modem response}
  2659.                 IF (Temp_Integer) THEN
  2660.                     Goto REDIAL_HANG_UP;
  2661.                 END;
  2662.                 Goto TIMEOUT_LOOP;
  2663.             END;
  2664.         END;
  2665.         Write(Str(T_Stop - T_Start),24,Menu_Y + 10,0,M_S_Color);
  2666.         IF (Check_Key) THEN
  2667.             IF (Key1 = 27) THEN
  2668.                 Goto ABORT_REDIAL;
  2669.             END;
  2670.             Jx := Inq_Key(Key1,Key2,TERM,MStr);
  2671.             IF ((Jx = 1) and (MStr = 'MECOM^COM_HELP')) THEN
  2672.                 Help('MECOM^PHONRED');
  2673.             END;
  2674.             IF ((Key1 = 0) and (Key2 = 60)) THEN
  2675.                 Set_Global_Int('IINT_1',Parse_Int('/RT=',Global_Str('Com_Modem_Params')));
  2676.                 Set_Global_Str('IPARM_1','/TP=1/C=1/L=1/W=2/H=MECOM^PHONRED/T=Redial timeout            ');
  2677.                 Set_Global_Int('IINT_2',Parse_Int('/RP=',Global_Str('Com_Modem_Params')));
  2678.                 Set_Global_Str('IPARM_2','/TP=1/C=1/L=2/W=2/H=MECOM^PHONRED/T=Redial pause              ');
  2679.  
  2680.                 RM( 'USERIN^DATA_IN /A=2/#=2/S=1/X=10/T=REDIAL PARAMS/Y=' + Str(Menu_Y + 13));
  2681.  
  2682.                 IF (Return_Int) THEN
  2683.                     Return_Str := '/RT=';
  2684.                     RM('USERIN^CHNGPARM /G=Com_Modem_Params/P=' + Str(Global_Int('IINT_1')));
  2685.                     Return_Str := '/RP=';
  2686.                     RM('CHNGPARM /G=Com_Modem_Params/P=' + Str(Global_Int('IINT_2')));
  2687.                 END;
  2688.  
  2689.                 Set_Global_Str('IPARM_0','');
  2690.                 Set_Global_Int('IINT_1',0);
  2691.                 Set_Global_Str('IPARM_1','');
  2692.                 Set_Global_Int('IINT_2',0);
  2693.                 Set_Global_Str('IPARM_2','');
  2694.                 Goto REDIAL_CHANGE;
  2695.             END;
  2696.         END;
  2697.         IF ((T_Stop - T_Start) >= Parse_Int('/RT=',Global_Str('Com_Modem_Params'))) THEN
  2698.             Modem_Response := 'TIMEOUT               ';
  2699.             Goto REDIAL_HANG_UP;
  2700.         END;
  2701.         Goto TIMEOUT_LOOP;
  2702.  
  2703. REDIAL_HANG_UP:
  2704.         Write(Modem_Response,31,Menu_Y + 12,0,M_S_Color);
  2705.         Call HANG_UP;
  2706. {This is just to clear the incoming port buffer}
  2707.         Return_Int := 255;
  2708.         Terminator_Chars := '';
  2709.         Call GET_MODEM_RESPONSE;
  2710.         Write('0 ',36,Menu_Y + 11,0,M_S_Color);
  2711.         Temp_Integer := Val(T_Start,Copy(Time,7,2));
  2712.  
  2713. DELAY_LOOP:
  2714.         Temp_Integer := Val(T_Stop,Copy(Time,7,2));
  2715.         IF (T_Start > T_Stop) THEN
  2716.             T_Stop := T_Stop + 60;
  2717.         END;
  2718.         Write(Str(T_Stop - T_Start),36,Menu_Y + 11,0,M_S_Color);
  2719.         IF (Check_Key) THEN
  2720.             IF (Key1 = 27) THEN
  2721.                 Goto ABORT_REDIAL;
  2722.             END;
  2723.         END;
  2724.         IF ((T_Stop - T_Start) >= Parse_Int('/RP=',Global_Str('Com_Modem_Params'))) THEN
  2725.             ++Redial_Count
  2726.             Goto REDIAL;
  2727.         END;
  2728.         Goto DELAY_LOOP;
  2729. ABORT_REDIAL:
  2730.         Return_Str := '';
  2731.         Call HANG_UP;
  2732.         Kill_Box;
  2733.     END;
  2734.  
  2735.     Goto EXIT;
  2736.  
  2737.  
  2738. {********************************** SUBROUTINES ******************************}
  2739. HANG_UP:
  2740.     Put_Box(9,Menu_Y + 6,22,Menu_Y + 9,0,M_B_Color,'',True);
  2741.     Write('Hanging up',10,Menu_Y + 7,0,Working_Color);
  2742.     IF (Parse_Int('/HM=',Global_Str('Com_Modem_Params'))) THEN
  2743. {Drop DTR method}
  2744.         Error := set_com(port_num,13,Parse_Int('/RTS=',Global_Str('Com_Line_Params')) shl 1);
  2745.         Delay(200);
  2746.         error := set_com(port_num,13,Parse_Int('/DTR=',Global_Str('Com_Line_Params'))
  2747.                             or (Parse_Int('/RTS=',Global_Str('Com_Line_Params')) shl 1));
  2748.     ELSE
  2749. {Send modem string method}
  2750.         Return_Str := Parse_Str('/H=',Global_Str('Com_Modem_Params'));
  2751.         Call WRITE_TO_PORT;
  2752.     END;
  2753.     Kill_Box;
  2754.     RET;
  2755.  
  2756. GET_MODEM_RESPONSE:
  2757.     Modem_Response := Temp_Char;
  2758.  
  2759. MORE_RESPONSE:
  2760.     Delay(50);
  2761.     Error := read_com_till(port_num,Return_Int * 2,Terminator_Chars,
  2762.         Temp_Char,Terminator_Index);
  2763.     Modem_Response := Modem_Response + Temp_Char;
  2764.     IF (Error = 0) THEN
  2765.         IF ((Terminator_Index = 0) and (Svl(Modem_Response) < Return_Int)) THEN
  2766.             Goto MORE_RESPONSE;
  2767.         END;
  2768.     END;
  2769.     RET;
  2770.  
  2771. WRITE_TO_PORT:
  2772. {This routine checks for the presence of any of the special modem translate
  2773. characters and replaces them with the proper character for output to the modem
  2774. then outputs the string to the modem}
  2775. {Check for carriage return char}
  2776.     Temp_Char := Parse_Str('/XC=',Global_Str('Com_Modem_Params'));
  2777.     IF (Temp_Char <> '|0') THEN
  2778. CHECK_FOR_CR:
  2779.         Return_Int := XPos(Temp_Char,Return_Str,1);
  2780.         IF (Return_Int) THEN
  2781.             Return_Str := Copy(Return_Str,1,Return_Int - 1) + '|13' +
  2782.                             Copy(Return_Str,Return_Int + 1,254);
  2783.             Goto CHECK_FOR_CR;
  2784.         END;
  2785.     END;
  2786. {Check for control character}
  2787.     Temp_Char := Parse_Str('/XT=',Global_Str('Com_Modem_Params'));
  2788.     IF (Temp_Char <> '|0') THEN
  2789. CHECK_FOR_CTRL:
  2790.         Return_Int := XPos(Temp_Char,Return_Str,1);
  2791.         IF (Return_Int) THEN
  2792.             Return_Str := Copy(Return_Str,1,Return_Int - 1) +
  2793.                                         Char(Ascii(Copy(Return_Str,Return_Int + 1,1)) - 64) +
  2794.                                         Copy(Return_Str,Return_Int + 2,254);
  2795.             Goto CHECK_FOR_CTRL;
  2796.         END;
  2797.     END;
  2798. {Check for escape character}
  2799.     Temp_Char := Parse_Str('/XE=',Global_Str('Com_Modem_Params'));
  2800.     IF (Temp_Char <> '|0') THEN
  2801. CHECK_FOR_ESC:
  2802.         Return_Int := XPos(Temp_Char,Return_Str,1);
  2803.         IF (Return_Int) THEN
  2804.             Return_Str := Copy(Return_Str,1,Return_Int - 1) + '|27' +
  2805.                                         Copy(Return_Str,Return_Int + 1,254);
  2806.             Goto CHECK_FOR_ESC;
  2807.         END;
  2808.     END;
  2809. {Check for 2 second delay char}
  2810.     Temp_Char := Parse_Str('/XP=',Global_Str('Com_Modem_Params'));
  2811.     IF (Temp_Char <> '|0') THEN
  2812. CHECK_FOR_DELAY:
  2813.         Return_Int := XPos(Temp_Char,Return_Str,1);
  2814.         IF (Return_Int) THEN
  2815.             error := write_com(port_num,Copy(Return_Str,1,Return_Int - 1), jx);
  2816.             Delay(2000);
  2817.             IF (Length(Return_Str) > Return_Int) THEN
  2818.                 Return_Str := Copy(Return_Str,Return_Int + 1,254);
  2819.                 Goto CHECK_FOR_DELAY;
  2820.             ELSE
  2821.                 RET;
  2822.             END;
  2823.         END;
  2824.     END;
  2825.     error := write_com(port_num,Return_Str, jx);
  2826.     RET;
  2827. CLEAN_GLOBALS:
  2828. {Deallocate variables used for DATA_IN}
  2829.     Jx := 0;
  2830.     WHILE (Jx < 9) DO
  2831.         Set_Global_Str( 'ISTR_' + Str(Jx),'');
  2832.         Set_Global_Int( 'IINT_' + Str(Jx),0);
  2833.         Set_Global_Str( 'IPARM_' + Str(Jx),'');
  2834.         ++Jx;
  2835.     END;
  2836.     RET;
  2837. {*****************************************************************************}
  2838.  
  2839. ESCAPE_EXIT:
  2840.     Return_Int :=  False;
  2841.     Goto SKIP_EXIT;
  2842.  
  2843. EXIT:
  2844.     Return_Int := True;
  2845. SKIP_EXIT:
  2846.     Call CLEAN_GLOBALS;
  2847.     IF (DIAL_Window) THEN
  2848.         Switch_Window(DIAL_Window);
  2849.         IF (File_Changed) THEN
  2850.             Save_File;
  2851.             Update_Status_Line;
  2852.         END;
  2853.         Delete_Window;
  2854.     END;
  2855.     Switch_Window(Active_Window);
  2856.     Reg_Exp_Stat := Temp_Reg_Exp_Stat;
  2857.     Insert_Mode := Temp_Insert_Mode;
  2858. END_MACRO;
  2859.  
  2860. $MACRO COM_SEND_BREAK;
  2861. {*******************************MULTI-EDIT MACRO*******************************
  2862.  
  2863. Name:    COM_SEND_BREAK
  2864.  
  2865. Description:    Invokes a break condition on the currently active com port.
  2866.  
  2867.                              (C) Copyright 1990 by American Cybernetics, Inc.
  2868. ******************************************************************************}
  2869.     Def_Int(Error);
  2870.     Error := Send_Break(Global_Int('COM_PORT_NUM'),
  2871.                         Parse_Int('/BL=',Global_Str('COM_TERMINAL_PARAMS')));
  2872.     IF (Error) THEN
  2873.         Error_Level := 6000 + Error;
  2874.         RM('MEERROR /EM=Error sending break signal.');
  2875.     END;
  2876. END_MACRO;
  2877.  
  2878. $MACRO COM_DUMB;
  2879. {*******************************MULTI-EDIT MACRO*******************************
  2880.  
  2881. Name:    COM_DUMB
  2882.  
  2883. Description:    The comunications module dumb terminal emulation.
  2884.  
  2885. Parameters:
  2886.                             /DO= A string to send to be processed by the terminal emulator.
  2887.                                      If present, the emulator will simply process and display
  2888.                                      the string and will not attempt to read any characters
  2889.                                      from the com port.  Useful in logon scripts.  This is NOT
  2890.                                      the normal mode of operation.
  2891.  
  2892.                              (C) Copyright 1990 by American Cybernetics, Inc.
  2893. ******************************************************************************}
  2894. {
  2895. This macro writes data to the terminal box from the comport in dumb terminal
  2896. emulation.
  2897. }
  2898.     Def_Int(Port_Num,Max_X,Max_Y,Scroll,Wrap,Terminator_Index,Error,Temp_Integer,
  2899.                     I_S_Length,Logging,ASCII_Download,Jx,Duplex,CR_LF_Out,Display_Only);
  2900.     Def_Str(Input_String[25],Terminators[3],Display_Only_Str,MStr);
  2901.     Def_Char(Ch,Bs_Char);
  2902.  
  2903.  
  2904.     Port_Num := Global_int('Com_Port_Num');
  2905.     Display_Only := XPos('/DO=',MParm_Str,1);
  2906.     IF (Display_Only) THEN
  2907.         Display_Only_Str := Copy(MParm_Str,Display_Only + 4,255);
  2908.     END;
  2909.     Bs_Char := Char(Parse_Int('/BK=',Global_Str('Com_Terminal_Params')));
  2910.     CR_LF_Out := Parse_Int('/CO=',Global_Str('Com_Terminal_Params'));
  2911.     Duplex := Parse_Int('/D=',Global_Str('Com_Terminal_Params'));
  2912.     Logging := Global_Int('Com_Logging');
  2913.     ASCII_Download := Global_Int('Com_ASCII_Download');
  2914.     GotoXY_Vp((Global_Int('Com_Cursor_Pos') and $FF),
  2915.                         (Global_Int('Com_Cursor_Pos') shr $08));
  2916.  
  2917. GET_STRING:
  2918.     IF (Display_Only) THEN
  2919.         IF (Display_Only_Str = '') THEN
  2920.             Goto EXIT;
  2921.         END;
  2922.         Error := 20;
  2923.         Temp_Integer := 1;
  2924.         Terminator_Index := 0;
  2925.         WHILE (Temp_Integer < 4) DO
  2926.             Jx := XPos(Copy('|8|10|13',Temp_Integer,1),Display_Only_Str,1);
  2927.             IF (Jx > 0) THEN
  2928.                 IF (Jx < Error) THEN
  2929.                     Error := Jx;
  2930.                     Terminator_Index := Temp_Integer;
  2931.                 END;
  2932.             END;
  2933.             ++Temp_Integer;
  2934.         END;
  2935.         Input_String := Copy(Display_Only_Str,1,Error);
  2936.         Display_Only_Str := Str_Del(Display_Only_Str,1,Error);
  2937.     ELSE
  2938.         Error := read_com_till(port_num, 20,'|8|10|13',Input_String,Terminator_Index);
  2939.     END;
  2940.     I_S_Length := SVL(Input_String);
  2941.     IF (I_S_Length) THEN
  2942. {If there is nothing special about this chunk of chars, just write it so as to
  2943. be as fast as possible.}
  2944.         IF ((Logging) or (ASCII_Download)) THEN
  2945.             Return_Int := Length(Global_Str('Com_Log_Str'));
  2946.             IF ((Return_Int + Svl(Input_String)) > 512) THEN
  2947.                 IF (Logging) THEN
  2948.                     Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Jx);
  2949.                     IF (Return_Int > Jx) THEN
  2950.                         Return_Int := 3241;
  2951.                         RM('COM_LOG_ERROR');
  2952.                         Goto ABORT_LOG;
  2953.                     END;
  2954.                     IF (Error) THEN
  2955.                         Return_Int := Error;
  2956.                         RM('COM_LOG_ERROR');
  2957.                         Goto ABORT_LOG;
  2958.                     END;
  2959.                 END;
  2960.                 IF (ASCII_Download) THEN
  2961.                     Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Jx);
  2962.                     IF (Return_Int > Jx) THEN
  2963.                         Return_Int := 3241;
  2964.                         RM('COM_LOG_ERROR /A=1');
  2965.                         Goto ABORT_LOG;
  2966.                     END;
  2967.                     IF (Error) THEN
  2968.                         Return_Int := Error;
  2969.                         RM('COM_LOG_ERROR /A=1');
  2970.                         Goto ABORT_LOG;
  2971.                     END;
  2972.                 END;
  2973.  
  2974.                 Set_Global_Str('Com_Log_Str','');
  2975.             END;
  2976.  
  2977.             IF (Terminator_Index = 1) THEN
  2978. {Back space}
  2979.                 Set_Global_Str('Com_Log_Str',Copy(Global_Str('Com_Log_Str'),1,Length(Global_Str('Com_Log_Str')) - 1) + Copy(Input_String,1,Svl(Input_String) - 1));
  2980.             ELSE
  2981.                 Set_Global_Str('Com_Log_Str',Global_Str('Com_Log_Str') + Input_String);
  2982.             END;
  2983. ABORT_LOG:
  2984.         END;
  2985.         Write_VP(Input_String);
  2986.     END;
  2987.  
  2988.     IF (Check_Key) THEN
  2989.         Jx := Inq_Key(Key1,Key2,TERM,MStr);
  2990.         IF ((Jx = 1) and (MStr <> '')) THEN
  2991.             Goto EXIT;
  2992.         ELSIF (Key1 = 0) THEN
  2993.             IF (Key2 = 250) THEN
  2994.                 Goto EXIT;
  2995.             END;
  2996.         ELSE
  2997. SEND_KEY:
  2998.             Ch := Char(Key1);
  2999.             IF (Key1 = 8) THEN
  3000.                 Ch := Bs_Char;
  3001.             END;
  3002.  
  3003. TRY_AGAIN:
  3004.             error := write_com(port_num,Ch,Jx);
  3005.             IF (Error = 7) THEN
  3006.                 Delay(10);
  3007.                 Goto TRY_AGAIN;
  3008.             END;
  3009.         {if CR xlation is CR/LF then send the LF}
  3010.  
  3011.             IF (Ch = '|13') THEN
  3012.                 IF (Cr_Lf_Out = 1) THEN
  3013. LF_AGAIN:
  3014.                     error := write_com(port_num,'|10',Jx);
  3015.                     IF (Error = 7) THEN
  3016.                         Delay(10);
  3017.                         Goto LF_AGAIN;
  3018.                     END;
  3019.                 END;
  3020.             END;
  3021.  
  3022.             IF (Duplex) THEN
  3023. WRITE_TO_SCREEN:
  3024.                 Write_Vp(Ch);
  3025. DO_LOG:
  3026.                 IF ((Logging = True) or (ASCII_Download = True)) THEN
  3027.                     IF (Duplex) THEN
  3028.                             IF (Ch = Bs_Char) THEN
  3029.         {Back space}
  3030.                                 Set_Global_Str('Com_Log_Str',Copy(Global_Str('Com_Log_Str'),1,Length(Global_Str('Com_Log_Str')) - 1));
  3031.                             ELSE
  3032.                                 Set_Global_Str('Com_Log_Str',Global_Str('Com_Log_Str') + Ch);
  3033.                             END;
  3034.                         Return_Int := Length(Global_Str('Com_Log_Str'));
  3035.                         IF (Return_Int > 512) THEN
  3036.                             IF (Logging) THEN
  3037.                                 Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Jx);
  3038.                                 IF (Return_Int > Jx) THEN
  3039.                                     Return_Int := 3241;
  3040.                                     RM('COM_LOG_ERROR');
  3041.                                     Goto ABORT_LOG2;
  3042.                                 END;
  3043.                                 IF (Error) THEN
  3044.                                     Return_Int := Error;
  3045.                                     RM('COM_LOG_ERROR');
  3046.                                     Goto ABORT_LOG2;
  3047.                                 END;
  3048.                             END;
  3049.                             IF (ASCII_Download) THEN
  3050.                                 Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Jx);
  3051.                                 IF (Return_Int > Jx) THEN
  3052.                                     Return_Int := 3241;
  3053.                                     RM('COM_LOG_ERROR /A=1');
  3054.                                     Goto ABORT_LOG2;
  3055.                                 END;
  3056.                                 IF (Error) THEN
  3057.                                     Return_Int := Error;
  3058.                                     RM('COM_LOG_ERROR /A=1');
  3059.                                     Goto ABORT_LOG2;
  3060.                                 END;
  3061.                             END;
  3062.                             Set_Global_Str('Com_Log_Str','');
  3063.                         END;
  3064.                     END;
  3065.                 END;
  3066. ABORT_LOG2:
  3067.             END;
  3068.             IF (Check_Key) THEN
  3069.                 Goto SEND_KEY;
  3070.             END;
  3071.         END;
  3072.     END;
  3073.     Goto GET_STRING;
  3074.  
  3075. EXIT:
  3076.     Set_Global_Int('Com_Cursor_Pos',WhereX_VP or (WhereY_Vp shl $08));
  3077. END_MACRO;
  3078.  
  3079. $MACRO COM_ANSI;
  3080. {*******************************MULTI-EDIT MACRO*******************************
  3081.  
  3082. Name:    COM_ANSI
  3083.  
  3084. Description:    The comunications module ANSI terminal emulation.
  3085.  
  3086. Parameters:
  3087.                             /DO= A string to send to be processed by the terminal emulator.
  3088.                                      If present, the emulator will simply process and display
  3089.                                      the string and will not attempt to read any characters
  3090.                                      from the com port.  Useful in logon scripts.  This is NOT
  3091.                                      the normal mode of operation.
  3092.  
  3093.                              (C) Copyright 1990 by American Cybernetics, Inc.
  3094. ******************************************************************************}
  3095. {
  3096. This macro writes data to the terminal box from the comport in ANSI terminal
  3097. emulation.
  3098. }
  3099.     Def_Int(Port_Num,Sequence_Type,Sequence_Index,Param_Int,Parm_Count,Tries,
  3100.                     Max_X,Max_Y,Scroll,key_wait,Terminator_Index,Error,
  3101.                     I_S_Length,Logging,Partial,Try_Count,Temp_Integer,Jx,ASCII_Download,
  3102.                     Cr_Lf_Out,Duplex,Display_Only);
  3103.     Def_Str(Ch[254],Input_String,Display_Only_Str,MStr);
  3104.     Def_Str(Temp_String,Sequence_Param);
  3105.     Def_Char(BS_Char);
  3106.  
  3107.     Bs_Char := Char(Parse_Int('/BK=',Global_Str('Com_Terminal_Params')));
  3108.     Display_Only := XPos('/DO=',MParm_Str,1);
  3109.     IF (Display_Only) THEN
  3110.         Display_Only_Str := Copy(MParm_Str,Display_Only + 4,255);
  3111.     END;
  3112.     CR_LF_Out := Parse_Int('/CO=',Global_Str('Com_Terminal_Params'));
  3113.     Duplex := Parse_Int('/D=',Global_Str('Com_Terminal_Params'));
  3114.     Port_Num := Global_int('Com_Port_Num');
  3115.     Logging := Global_Int('Com_logging');
  3116.     ASCII_Download := Global_Int('Com_ASCII_Download');
  3117.     GotoXY_Vp((Global_Int('Com_Cursor_Pos') and $FF),
  3118.                         (Global_Int('Com_Cursor_Pos') shr $08));
  3119.  
  3120.     Partial := Global_Str('Partial_Sequence') <> '';
  3121.     IF (Partial) THEN
  3122.         Temp_String := Global_Str('Partial_Sequence');
  3123.         Goto ESCAPE_SEQUENCE;
  3124.     END;
  3125.  
  3126.  
  3127.     Set_Global_Str('Partial_Sequence','');
  3128.  
  3129.  
  3130. GET_STRING:
  3131.     IF (Display_Only) THEN
  3132.         IF (Display_Only_Str = '') THEN
  3133.             Goto EXIT;
  3134.         END;
  3135.         Error := 20;
  3136.         Temp_Integer := 1;
  3137.         Terminator_Index := 0;
  3138.         WHILE (Temp_Integer < 6) DO
  3139.             Jx := XPos(Copy('|8|10|13|27|12',Temp_Integer,1),Display_Only_Str,1);
  3140.             IF (Jx > 0) THEN
  3141.                 IF (Jx < Error) THEN
  3142.                     Error := Jx;
  3143.                     Terminator_Index := Temp_Integer;
  3144.                 END;
  3145.             END;
  3146.             ++Temp_Integer;
  3147.         END;
  3148.  
  3149.         Input_String := Copy(Display_Only_Str,1,Error);
  3150.         Display_Only_Str := Str_Del(Display_Only_Str,1,Error);
  3151.     ELSE
  3152.         Error := read_com_till(port_num, 20,'|8|10|13|27|12',Input_String,Terminator_Index);
  3153.     END;
  3154.     I_S_Length := SVL(Input_String);
  3155.     IF (I_S_Length) THEN
  3156. {If there is nothing special about this chunk of chars, just write it so as to
  3157. be as fast as possible.}
  3158.         IF (Terminator_Index > 3) THEN
  3159.             Input_String := Copy(Input_String,1,I_S_Length - 1);
  3160.         End;
  3161.         IF ((Logging) or (ASCII_Download)) THEN
  3162.             Return_Int := Length(Global_Str('Com_Log_Str'));
  3163.             IF ((Return_Int + Svl(Input_String)) > 512) THEN
  3164.                 IF (Logging) THEN
  3165.                     Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Jx);
  3166.                     IF (Return_Int > Jx) THEN
  3167.                         Return_Int := 3241;
  3168.                         RM('COM_LOG_ERROR');
  3169.                         Goto ABORT_LOG;
  3170.                     END;
  3171.                     IF (Error) THEN
  3172.                         Return_Int := Error;
  3173.                         RM('COM_LOG_ERROR');
  3174.                         Goto ABORT_LOG;
  3175.                     END;
  3176.                 END;
  3177.                 IF (ASCII_Download) THEN
  3178.                     Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Jx);
  3179.                     IF (Return_Int > Jx) THEN
  3180.                         Return_Int := 3241;
  3181.                         RM('COM_LOG_ERROR /A=1');
  3182.                         Goto ABORT_LOG;
  3183.                     END;
  3184.                     IF (Error) THEN
  3185.                         Return_Int := Error;
  3186.                         RM('COM_LOG_ERROR /A=1');
  3187.                         Goto ABORT_LOG;
  3188.                     END;
  3189.                 END;
  3190.  
  3191.                 Set_Global_Str('Com_Log_Str','');
  3192.             END;
  3193.  
  3194.             IF (Terminator_Index = 1) THEN
  3195. {Back space}
  3196.                 Set_Global_Str('Com_Log_Str',Copy(Global_Str('Com_Log_Str'),1,Length(Global_Str('Com_Log_Str')) - 1) + Copy(Input_String,1,Svl(Input_String) - 1));
  3197.             ELSE
  3198.                 Set_Global_Str('Com_Log_Str',Global_Str('Com_Log_Str') + Input_String);
  3199.             END;
  3200.     ABORT_LOG:
  3201.         END;
  3202.  
  3203.         Write_VP(Input_String);
  3204. {Process a form feed character by clearing the screen}
  3205.         IF (Terminator_Index = 5) THEN
  3206.             Clr_Vp;
  3207.         END;
  3208.         IF (Terminator_Index = 4) THEN
  3209. ESCAPE_SEQUENCE:
  3210.             Call DECODE_SEQUENCE;
  3211.             IF (Partial) THEN
  3212.                 Set_Global_Str('Partial_Sequence',Temp_String);
  3213.                 Goto EXIT;
  3214.             END;
  3215.         END;
  3216.     END;
  3217.  
  3218.     IF (Check_Key) THEN
  3219.         Jx := Inq_Key(Key1,Key2,TERM,MStr);
  3220.         IF ((Jx = 1) and (MStr <> '')) THEN
  3221.             Goto EXIT;
  3222.         ELSIF (Key1 = 0) THEN
  3223.             IF (Key2 = 250) THEN
  3224.                 Goto EXIT;
  3225.             END;
  3226.         ELSE
  3227. SEND_KEY:
  3228.             Ch := Char(Key1);
  3229.             IF (Key1 = 8) THEN
  3230.                 Ch := Bs_Char;
  3231.             END;
  3232.  
  3233. TRY_AGAIN:
  3234.             error := write_com(port_num,Ch,Jx);
  3235.             IF (Error = 7) THEN
  3236.                 Delay(10);
  3237.                 Goto TRY_AGAIN;
  3238.             END;
  3239.         {if CR xlation is CR/LF then send the LF}
  3240.  
  3241.             IF (Ch = '|13') THEN
  3242.                 IF (Cr_Lf_Out = 1) THEN
  3243. LF_AGAIN:
  3244.                     error := write_com(port_num,'|10',Jx);
  3245.                     IF (Error = 7) THEN
  3246.                         Delay(10);
  3247.                         Goto LF_AGAIN;
  3248.                     END;
  3249.                 END;
  3250.             END;
  3251.  
  3252.             IF (Duplex) THEN
  3253. WRITE_TO_SCREEN:
  3254.                 Write_Vp(Ch);
  3255. DO_LOG:
  3256.                 IF ((Logging = True) or (ASCII_Download = True)) THEN
  3257.                     IF (Duplex) THEN
  3258.                             IF (Ch = Bs_Char) THEN
  3259.         {Back space}
  3260.                                 Set_Global_Str('Com_Log_Str',Copy(Global_Str('Com_Log_Str'),1,Length(Global_Str('Com_Log_Str')) - 1));
  3261.                             ELSE
  3262.                                 Set_Global_Str('Com_Log_Str',Global_Str('Com_Log_Str') + Ch);
  3263.                             END;
  3264.                         Return_Int := Length(Global_Str('Com_Log_Str'));
  3265.                         IF (Return_Int > 512) THEN
  3266.                             IF (Logging) THEN
  3267.                                 Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Jx);
  3268.                                 IF (Return_Int > Jx) THEN
  3269.                                     Return_Int := 3241;
  3270.                                     RM('COM_LOG_ERROR');
  3271.                                     Goto ABORT_LOG2;
  3272.                                 END;
  3273.                                 IF (Error) THEN
  3274.                                     Return_Int := Error;
  3275.                                     RM('COM_LOG_ERROR');
  3276.                                     Goto ABORT_LOG2;
  3277.                                 END;
  3278.                             END;
  3279.                             IF (ASCII_Download) THEN
  3280.                                 Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_ASCII_Handle'),Jx);
  3281.                                 IF (Return_Int > Jx) THEN
  3282.                                     Return_Int := 3241;
  3283.                                     RM('COM_LOG_ERROR /A=1');
  3284.                                     Goto ABORT_LOG2;
  3285.                                 END;
  3286.                                 IF (Error) THEN
  3287.                                     Return_Int := Error;
  3288.                                     RM('COM_LOG_ERROR /A=1');
  3289.                                     Goto ABORT_LOG2;
  3290.                                 END;
  3291.                             END;
  3292.                             Set_Global_Str('Com_Log_Str','');
  3293.                         END;
  3294.                     END;
  3295.                 END;
  3296. ABORT_LOG2:
  3297.             END;
  3298.             IF (Check_Key) THEN
  3299.                 Goto SEND_KEY;
  3300.             END;
  3301.         END;
  3302.     END;
  3303.     Goto GET_STRING;
  3304.  
  3305.  
  3306. {********************************** SUBROUTINES ******************************}
  3307. DECODE_SEQUENCE:
  3308. {This routine decodes ANSI escape sequences}
  3309.     IF (Partial = False) THEN
  3310.         Temp_String := '';
  3311.     END;
  3312.     Partial := False;
  3313.     Try_Count := 0;
  3314.  
  3315. READ_AGAIN:
  3316.     ++Try_Count;
  3317.     IF (Display_Only) THEN
  3318.         IF (Display_Only_Str = '') THEN
  3319.             Goto EXIT;
  3320.         END;
  3321.         Error := 254;
  3322.         Temp_Integer := 1;
  3323.         Terminator_Index := 0;
  3324.         WHILE (Temp_Integer < 15) DO
  3325.             Jx := XPos(Copy('HFmhlABCDnJsuK',Temp_Integer,1),Display_Only_Str,1);
  3326.             IF (Jx > 0) THEN
  3327.                 IF (Jx < Error) THEN
  3328.                     Error := Jx;
  3329.                     Terminator_Index := Temp_Integer;
  3330.                 END;
  3331.             END;
  3332.             ++Temp_Integer;
  3333.         END;
  3334.         Input_String := Copy(Display_Only_Str,1,Error);
  3335.         Display_Only_Str := Str_Del(Display_Only_Str,1,Error);
  3336.     ELSE
  3337.         Error := read_com_till(port_num, 254,'HFmhlABCDnJsuK', Input_String,Terminator_Index);
  3338.     END;
  3339.     I_S_Length := SVL(Input_String);
  3340.     Temp_String := Temp_String + Input_String;
  3341.     IF (I_S_Length = 0) THEN
  3342.         IF ((Check_Key = True) or (Display_Only = True)) THEN
  3343.             Partial := True;
  3344.             Ret;
  3345.         ELSE
  3346.             Goto READ_AGAIN;
  3347.         END;
  3348.     END;
  3349.     IF (Terminator_Index = 0) THEN
  3350.         IF (Check_Key) THEN
  3351.             Partial := True;
  3352.             Ret;
  3353.         ELSE
  3354.             IF (SVL(Temp_String) > 200) THEN
  3355.                 Input_String := Temp_String;
  3356.                 Ret;
  3357.             END;
  3358.             Goto READ_AGAIN;
  3359.         END;
  3360.     END;
  3361.     IF (Copy(Temp_String,1,1) <> '[') THEN
  3362.         Input_String := Temp_String;
  3363.         Ret;
  3364.     END;
  3365.     Input_String := '';
  3366.     IF (Terminator_Index > 9) THEN
  3367.         IF (Terminator_Index = 10) THEN
  3368. {Device status report.  Don't know how to do this one.}
  3369.         END;
  3370.         IF (Terminator_Index = 11) THEN
  3371. {Erase display}
  3372.             Sequence_Index := 1;
  3373.             Call GET_SEQUENCE_PARAM;
  3374.             IF (Param_Int < 1) THEN
  3375. {Erase from cursor to bottom of screen, don't move cursor.}
  3376.                 Error := Parse_Int('/X2=',Global_Str('Com_Cur_Scrn_Params')) -
  3377.                     Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params')) - 1;
  3378. {
  3379.                 Draw_Char(32,WhereX_Vp,whereY_vp,
  3380.                     ((Text_Color_VP and $F) or (Text_Back_Vp shl 4)),
  3381.                     Error - WhereX_Vp + 1);
  3382. }
  3383.                 Temp_Integer := Wherey;
  3384.                 Draw_Char(32,WhereX,whereY,
  3385.                     ((Text_Color_VP and $F) or (Text_Back_Vp shl 4)),
  3386.                     Error - WhereX_Vp + 1);
  3387. {
  3388.                 Temp_Integer := Wherey_vp;
  3389. }
  3390.                 Jx := Parse_Int('/Y2=',Global_Str('Com_Cur_Scrn_Params')) - 1;
  3391.                 Tries := Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params')) + 1;
  3392.  
  3393.                 WHILE (Temp_Integer < Jx) DO
  3394.                     ++Temp_Integer;
  3395.                     Draw_Char(32,Tries,Temp_Integer,
  3396.                         ((Text_Color_VP and $F) or (Text_Back_Vp shl 4)),Error);
  3397.                 END;
  3398.             ELSIF (Param_Int = 2) THEN
  3399. {Erase entire display.}
  3400.                 Clr_Vp;
  3401.             END;
  3402.         END;
  3403.         IF (Terminator_Index = 12) THEN
  3404. {Save Cursor}
  3405.             Set_Global_Int('Com_Temp_Cursor',(Wherex_Vp) or (WhereY_VP shl $08));
  3406.         END;
  3407.         IF (Terminator_Index = 13) THEN
  3408. {Restore cursor}
  3409.             GotoXY_Vp(Global_Int('Com_Temp_Cursor') and $FF,Global_Int('Com_Temp_Cursor') shr $08);
  3410.         END;
  3411.         IF (Terminator_Index = 14) THEN
  3412. {Erase line}
  3413.                 Draw_Char(32,WhereX,whereY,
  3414.                     ((Text_Color_VP and $F) or (Text_Back_Vp shl 4)),
  3415.                     (Parse_Int('/X2=',Global_Str('Com_Cur_Scrn_Params')) -
  3416.                     Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params'))) -
  3417.                     WhereX_Vp);
  3418.  
  3419. {
  3420.                 Draw_Char(32,WhereX_Vp,whereY_vp,
  3421.                     ((Text_Color_VP and $F) or (Text_Back_Vp shl 4)),
  3422.                     (Parse_Int('/X2=',Global_Str('Com_Cur_Scrn_Params')) -
  3423.                     Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params'))) -
  3424.                     WhereX_Vp);
  3425. }
  3426.         END;
  3427.     END;
  3428.     Sequence_Index := 1;
  3429.     IF (Terminator_Index > 5) THEN
  3430.         Call GET_SEQUENCE_PARAM;
  3431.         IF (Param_Int = -1) THEN
  3432.             Param_Int := 1;
  3433.         END;
  3434.         IF (Terminator_Index = 6) THEN
  3435. {Cursor up}
  3436.             GotoXY_VP(WhereX_VP,WhereY_VP - Param_Int);
  3437.         END;
  3438.         IF (Terminator_Index = 7) THEN
  3439. {Cursor down}
  3440.             GotoXY_VP(WhereX_VP,WhereY_VP + Param_Int);
  3441.         END;
  3442.         IF (Terminator_Index = 8) THEN
  3443. {Cursor right}
  3444.             GotoXY_VP(WhereX_VP + Param_Int,WhereY_VP);
  3445.         END;
  3446.         IF (Terminator_Index = 9) THEN
  3447. {Cursor left}
  3448.             GotoXY_VP(WhereX_VP - Param_Int,WhereY_VP);
  3449.         END;
  3450.         Ret;
  3451.     END;
  3452.     IF (Terminator_Index < 3) THEN
  3453. {Cusor_Position}
  3454.         Call GET_SEQUENCE_PARAM;
  3455.         IF (Param_Int < 1) THEN
  3456.             Param_Int := 1;
  3457.         END;
  3458.         Temp_Integer := Param_Int;
  3459.         Call GET_SEQUENCE_PARAM;
  3460.         IF (Param_Int < 1) THEN
  3461.             Param_Int := 1;
  3462.         END;
  3463.         GotoXY_Vp(Param_Int,Temp_Integer);
  3464.     END;
  3465.     IF (Terminator_Index = 3) THEN
  3466. {Set graphics rendition.}
  3467. GRAPHICS_PARAMS:
  3468.         Call GET_SEQUENCE_PARAM;
  3469.         IF (Param_Int > -1) THEN
  3470.             IF (Param_Int = 0) THEN
  3471. {all attributes off.  I think this means bold, underline, etc. off but
  3472. colors remain.}
  3473.                 Text_Color_VP := Text_Color_Vp and $77;
  3474. {on monochrome screens, if foreground color is blue or underline, we need to
  3475. change it to white.}
  3476.                 IF (XPos(Char(Video_Card),'|1|3|6|7|9',1)) THEN
  3477.                     IF ((Text_Color_Vp and $7) = Blue) THEN
  3478.                         Text_Color_Vp := (Text_Color_Vp and $70) or $7;
  3479.                     END;
  3480.                 END;
  3481.             END;
  3482.             IF (Param_Int = 1) THEN
  3483. {Bold on}
  3484.                 Text_Color_VP := Text_Color_VP or $8;
  3485.             END;
  3486.             IF (Param_Int = 2) THEN
  3487. {Faint on}
  3488.                 Text_Color_VP := Text_Color_VP and $F7;
  3489.             END;
  3490.             IF (Param_Int = 3) THEN
  3491. {Italic on.   sorry, can't do this one}
  3492.             END;
  3493.             IF ((Param_Int = 5) or (Param_Int = 6)) THEN
  3494. {Blink}
  3495.                 Text_Color_VP := Text_Color_VP or $80;
  3496.             END;
  3497.             IF (Param_Int = 7) THEN
  3498. {Reverse video}
  3499.                 Text_Color_VP :=
  3500.                     (Text_Color_VP and $8) or ((Text_Color_VP shr 4) and $7) or
  3501.                     ((((Text_Color_Vp and $80) shr 4) or (Text_Color_Vp and $7)) shl 4);
  3502.             END;
  3503.             IF (Param_Int = 8) THEN
  3504. {Concealed on  I presume this means both foreground and background are the same}
  3505.                 Text_Color_VP :=
  3506.                     (Text_Color_VP and $8) or ((Text_Color_VP shr 4) and $7) or
  3507.                     (Text_Color_Vp and $F0);
  3508.             END;
  3509.  
  3510. {30 - 47 are change colors.  We mask all but bold and blink bits then OR with
  3511. color so we won't cancell out previous bold or blink attributes.}
  3512.             IF (Param_Int = 30) THEN
  3513. {Black foreground}
  3514.                 Text_Color_VP := (Text_Color_VP and $F8) or Black;
  3515.             END;
  3516.             IF (Param_Int = 31) THEN
  3517. {Red foreground}
  3518.                 Text_Color_VP := (Text_Color_VP and $F8) or Red;
  3519.             END;
  3520.             IF (Param_Int = 32) THEN
  3521. {Green foreground}
  3522.                 Text_Color_VP := (Text_Color_VP and $F8) or Green;
  3523.             END;
  3524.             IF (Param_Int = 33) THEN
  3525. {Yellow foreground}
  3526.                 Text_Color_VP := (Text_Color_VP and $F8) or Brown;
  3527.             END;
  3528.             IF (Param_Int = 34) THEN
  3529. {Blue foreground}
  3530.                 Text_Color_VP := (Text_Color_VP and $F8) or Blue;
  3531.             END;
  3532.             IF (Param_Int = 35) THEN
  3533. {Magenta foreground}
  3534.                 Text_Color_VP := (Text_Color_VP and $F8) or Magenta;
  3535.             END;
  3536.             IF (Param_Int = 36) THEN
  3537. {Cyan foreground}
  3538.                 Text_Color_VP := (Text_Color_VP and $F8) or Cyan;
  3539.             END;
  3540.             IF (Param_Int = 37) THEN
  3541. {White foreground}
  3542.                 Text_Color_VP := (Text_Color_VP and $F8) or LightGray;
  3543.             END;
  3544.             IF (Param_Int = 40) THEN
  3545. {Black background}
  3546.                 Text_Color_VP := (Text_Color_VP and $8F) or (Black shl 4);
  3547.             END;
  3548.             IF (Param_Int = 41) THEN
  3549. {Red background}
  3550.                 Text_Color_VP := (Text_Color_VP and $8F) or (Black shl 4);
  3551.             END;
  3552.             IF (Param_Int = 42) THEN
  3553. {Green background}
  3554.                 Text_Color_VP := (Text_Color_VP and $8F) or (green shl 4);
  3555.             END;
  3556.             IF (Param_Int = 43) THEN
  3557. {Yellow background}
  3558.                 Text_Color_VP := (Text_Color_VP and $8F) or (brown shl 4);
  3559.             END;
  3560.             IF (Param_Int = 44) THEN
  3561. {Blue background}
  3562.                 Text_Color_VP := (Text_Color_VP and $8F) or (blue shl 4);
  3563.             END;
  3564.             IF (Param_Int = 45) THEN
  3565. {Magenta background}
  3566.                 Text_Color_VP := (Text_Color_VP and $8F) or (magenta shl 4);
  3567.             END;
  3568.             IF (Param_Int = 46) THEN
  3569. {Cyan background}
  3570.                 Text_Color_VP := (Text_Color_VP and $8F) or (cyan shl 4);
  3571.             END;
  3572.             IF (Param_Int = 47) THEN
  3573. {White background}
  3574.                 Text_Color_VP := (Text_Color_VP and $8F) or (lightgray shl 4);
  3575.             END;
  3576.             IF (Param_Int = 48) THEN
  3577. {Subscript background}
  3578.             END;
  3579.             IF (Param_Int = 49) THEN
  3580. {Superscript background}
  3581.             END;
  3582.             Goto GRAPHICS_PARAMS;
  3583.         END;
  3584.         Ret;
  3585.     END;
  3586.     IF (Terminator_Index = 4) THEN
  3587. {Set mode.  Don't really know how to do this.}
  3588.     END;
  3589.     IF (Terminator_Index = 5) THEN
  3590. {Reset mode.  Don't really know how to do this.}
  3591.     END;
  3592.     RET;
  3593.  
  3594. GET_SEQUENCE_PARAM:
  3595.     ++Sequence_Index;
  3596.     Sequence_Param := '';
  3597.     WHILE (XPos(Copy(Temp_String,Sequence_Index,1),'0123456789',1)) DO
  3598.         Sequence_Param := Sequence_Param + Copy(Temp_String,Sequence_Index,1);
  3599.         ++Sequence_Index;
  3600.     END;
  3601.     IF (Sequence_Param = '') THEN
  3602.         Goto NO_GOOD;
  3603.     END;
  3604.     Return_Int := Val(Param_Int,Sequence_Param);
  3605.     IF (Return_Int) THEN
  3606. NO_GOOD:
  3607.         Param_Int := -1;
  3608.     END;
  3609.     RET;
  3610. {*****************************************************************************}
  3611.  
  3612. EXIT:
  3613.     Set_Global_Int('Com_Cursor_Pos',WhereX_VP or (WhereY_Vp shl $08));
  3614. END_MACRO;
  3615.  
  3616. $MACRO COM_INIT DUMP;
  3617. {*******************************MULTI-EDIT MACRO*******************************
  3618.  
  3619. Name:    COM_INIT
  3620.  
  3621. Description:    The comunications module initialization routine.  Creates a
  3622. window to load the file 'MECOM.DB' and gets all the initialization parameters
  3623. and stores them into global variables.  If the file or any part of the file is
  3624. not found, then defaults will be assigned.
  3625.  
  3626.                              (C) Copyright 1990 by American Cybernetics, Inc.
  3627. ******************************************************************************}
  3628. {
  3629. Set_Global_Str('Com_General_Params','/GENERAL=/DP=/UP=/LF=MECOM.LOG/A=1/VWW=0/VRM=0/MWW=0/MRM=0');
  3630. Set_Global_Str('Com_Box_Params','/BOX=/X1=10/Y1=5/X2=77/Y2=23');
  3631. Set_Global_Str('Com_Color_Params','/COLOR=/F=15/B=0');
  3632. Set_Global_Str('Com_Screen_Params','/SCREEN=/FS=1/SR=0');
  3633. Set_Global_Str('Com_Modem_Params','/MODEM=/XP=~/XC=!/XT=^/XE=||/I=ATE1 M1 V1 X1/H=~+++~ATH0!/DS=!/DC=ATDT/CS=CONNECT/HM=1/NC1=BUSY/NC2=VOICE/NC3=NO CARRIER/NC4=/RT=30/RP=2');
  3634. Set_Global_Str('Com_Terminal_Params','/TERMINAL=/T=DUMB/D=0/CI=0/CO=0/BT=1/BK=8/W=0/BL=2');
  3635. Set_Global_Str('Com_Line_Params','/LINE=/C=3/B=4/P=0/D=3/S=0/IB=2000/OB=200/XON=0/CTS=0/DTR=0/RTS=0/A1=1016/I1=4/T1=0/A2=760/I2=3/T2=0/A3=1000/I3=4/T3=0/A4=744/I4=3/T4=0/A5=16928/I5=3/T5=0/A6=16936/I6=3/T6=0/A7=21024/I7=3/T7=0/A8=21032/I8=3/T8=0');
  3636. Set_Global_Str('Com_Ascii_Params','/ASCII=/E=0/S=0/PC=0/CP=15/LP=10/CU=0/LU=2/CD=0/LD=0');
  3637.  
  3638. This one is no longer used.  These parameters are now associated with the
  3639. autodial phone list.
  3640. Set_Global_Str('Com_Logon_Params','/LOGON=/F=/L=/P=');
  3641. }
  3642.     Def_Int(Start_Line,Search_Amount,Jx);
  3643.  
  3644.     return_str := 'MECOM.DB';
  3645.     RM('MakeUserPath /DF=1');
  3646.     Return_Str := Caps(Fexpand(Return_Str));
  3647.     IF (Not(Switch_File(Return_Str))) THEN
  3648.         Switch_Window(Window_Count);
  3649.         Create_Window;
  3650.         file_name := Return_Str;
  3651.         Load_File(File_Name);
  3652.         File_Changed := False;
  3653.     END;
  3654.  
  3655.     window_attr := $81;
  3656.     Set_Global_Int('Com_Init_Window',Window_Id);
  3657.     Tof;
  3658.  
  3659. {If this file is empty, don't continue}
  3660.     IF (At_Eof) THEN
  3661.         Error_Level := 3002;
  3662.         RM('MEERROR /EM=CAN''T FIND: ' + Return_Str + ', OR FILE IS EMPTY!  ABORTING MECOM INITIALIZATON.  PLEASE EXIT MECOM AND CORRECT THIS PROBLEM.');
  3663.         Goto EXIT;
  3664.     END;
  3665. {Find the page title INITCOM.ME or create if not there}
  3666.     IF (Search_Fwd('|12INITCOM.ME',0) = 0) THEN
  3667.         Eof;
  3668.         IF (C_Col > 1) THEN
  3669.             Down;
  3670.         END;
  3671.         Put_Line('|12INITCOM.ME');
  3672.     END;
  3673. {Save the beginning position}
  3674.     Start_Line := C_Line;
  3675.     Eol;
  3676. {Find the next page title or EOF}
  3677.     IF (Search_Fwd('|12',0) = 0) THEN
  3678.         Eof;
  3679.         IF (C_Col > 1) THEN
  3680.             Down;
  3681.         END;
  3682.     END;
  3683.  
  3684.     Search_Amount := C_Line - Start_Line;
  3685.  
  3686.     Error_Level := 0;
  3687.     Update_Status_Line;
  3688.  
  3689.     Return_Str := '/GENERAL=/DP=/UP=/LF=MECOM.LOG/A=1/VWW=0/VRM=0/MWW=0/MRM=0';
  3690.     Call RETRIEVE_DATA;
  3691.  
  3692.     Return_Str := '/BOX=/X1=10/Y1=5/X2=77/Y2=23';
  3693.     Call RETRIEVE_DATA;
  3694.  
  3695.     Return_Str := '/COLOR=/F=15/B=0';
  3696.     Call RETRIEVE_DATA;
  3697.  
  3698.     Return_Str := '/SCREEN=/FS=1/SR=0';
  3699.     Call RETRIEVE_DATA;
  3700.  
  3701.     Return_Str := '/MODEM=/XP=~/XC=!/XT=^/XE=||/I=ATE1 M1 V1 X1/H=~+++~ATH0!/DS=!/DC=ATDT/CS=CONNECT/HM=1/NC1=BUSY/NC2=VOICE/NC3=NO CARRIER/NC4=/RT=30/RP=2';
  3702.     Call RETRIEVE_DATA;
  3703.  
  3704.     Return_Str := '/TERMINAL=/T=DUMB/D=0/CI=0/CO=0/BT=1/BK=8/W=0/BL=2';
  3705.     Call RETRIEVE_DATA;
  3706.  
  3707.     Return_Str := '/LINE=/C=3/B=4/P=0/D=3/S=0/IB=2000/OB=200/XON=0/CTS=0/DTR=0/RTS=0/A1=1016/I1=4/T1=0/A2=760/I2=3/T2=0/A3=1000/I3=4/T3=0/A4=744/I4=3/T4=0/A5=16928/I5=3/T5=0/A6=16936/I6=3/T6=0/A7=21024/I7=3/T7=0/A8=21032/I8=3/T8=0';
  3708.     Call RETRIEVE_DATA;
  3709.  
  3710.     Return_Str := '/ASCII=/E=0/S=0/PC=0/CP=15/LP=10/CU=0/LU=2/CD=0/LD=0';
  3711.     Call RETRIEVE_DATA;
  3712.  
  3713.     GOTO EXIT;
  3714.  
  3715. RETRIEVE_DATA:
  3716.     Jx := XPos('=',Return_Str,2);
  3717.     Goto_Line(Start_Line);
  3718.     IF (Search_Fwd(Copy(Return_Str,1,Jx),Search_Amount)) THEN
  3719.         Set_Global_Str('Com_' + Copy(Return_Str,2,Jx - 2) + '_Params',Get_Line);
  3720.     ELSE
  3721.         Set_Global_Str('Com_' + Copy(Return_Str,2,Jx - 2) + '_Params',Return_Str);
  3722.         Eol;
  3723.         ++Search_Amount;
  3724.         Insert_Mode := True;
  3725.         Cr;
  3726.         Put_Line(Return_Str);
  3727.     END;
  3728.     RET;
  3729.  
  3730. EXIT:
  3731. {save info about this window for future reference}
  3732.     Set_Global_Str('COM_INIT_WINDOW','/WI=' + Str(Window_Id) + '/SL=' +
  3733.                                     Str(Start_Line) + '/SA=' + Str(Search_Amount));
  3734. {If we had to put any stuff in this file, save it.}
  3735.     IF (File_Changed) THEN
  3736.         Save_File;
  3737.     END;
  3738.  
  3739. END_MACRO;
  3740.  
  3741. $MACRO COM_WAIT_FOR_STR;
  3742. {*******************************MULTI-EDIT MACRO*******************************
  3743.  
  3744. Name:    COM_WAIT_FOR_STR
  3745.  
  3746. Description:    A comunications module macro.  Waits until a specified string
  3747.                             or one of a set of strings is received from the com port or the
  3748.                             specified timeout occurs.  All characters recieved during this
  3749.                             macro will be sent to the    terminal emulator and are subject to
  3750.                             being interpreted and    displayed.
  3751.  
  3752. Parameters:
  3753.                     /S1= - /Snn= The desired string(s).  If there is more than one,
  3754.                     it will wait for the first occurance of any of them.
  3755.                     /T=  If 0, timeout is infinite.  If > 0 number of seconds.
  3756.                     /EI= Echo interval.  The time base is PC clock ticks, or 18.2 ticks
  3757.                              per second.  Characters will continue to accumulate in a 200 byte
  3758.                              buffer until the buffer is full, or the echo interval has lapsed.
  3759.                              The contents of the buffer are then sent to the terminal emulator
  3760.                              macro for displaying on the screen. The longer the interval, the
  3761.                              more characters can be potentially recieved before timeout
  3762.                              occurs.   The shorter the interval, the smoother the echo of
  3763.                              characters to the screen.  The reason for this trade-off is
  3764.                              because of the overhead of calling the terminal emulator to
  3765.                              display the accumulated characters.  The default is 9, or
  3766.                              approximately 1/2 second.
  3767.  
  3768. Returns:
  3769.  
  3770.                     Return_Int > 0        Successful, nn = number corresponding to /Snn=.
  3771.                     Return_Int = 0        timeout
  3772.                     Return_Int = -1   User aborted by pressing <ESC>
  3773.                     Return_Int = -2   Invalid parameters.  I.e, timeout is infinite,
  3774.                                                         and there are no strings to wait for.  Obviously,
  3775.                                                         this would cause an infinite loop.
  3776.  
  3777.                              (C) Copyright 1990 by American Cybernetics, Inc.
  3778. ******************************************************************************}
  3779.     Def_Str(Display_Str,Match_Str,Mac_Str[30]);
  3780.     Def_Int(Error,Port_Num,End_Time,Timeout,Matching,Return_Code,Echo_Interval,Echo_End,
  3781.                     String_Count,Match_Index);
  3782.     Def_Char(Ch);
  3783.  
  3784.     String_Count := 0;
  3785. GET_STRINGS:
  3786.     Display_Str := Parse_Str('/S' + Str(String_Count + 1) + '=',MParm_Str);
  3787.     IF (Display_Str <> '') THEN
  3788.         ++String_Count;
  3789.         Set_Global_Str('COM_MATCH_STR' + Str(String_Count),Caps(Display_Str));
  3790.         Goto GET_STRINGS;
  3791.     END;
  3792.  
  3793.     Timeout := Parse_Int('/T=',MParm_Str);
  3794.     IF (Timeout < 1) THEN
  3795.         Timeout := 0;
  3796.     END;
  3797. {We will not allow an infinite timeout when there is no string to wait for}
  3798.     IF (Timeout = 0) THEN
  3799.         IF (String_Count = 0) THEN
  3800.             Return_Code := -2;
  3801.             Goto ABORT;
  3802.         END;
  3803.     END;
  3804.  
  3805.     port_num := global_int('COM_PORT_NUM');
  3806.     Mac_Str := 'MECOM^COM_' + Parse_Str('/T=',Global_Str('Com_Terminal_Params')) +
  3807.             ' /DO=';
  3808.     Return_Str := Caps(Return_Str);
  3809.     Display_Str := '';
  3810.     Match_Str := '';
  3811.     Matching := False;
  3812.  
  3813.     Echo_Interval := Parse_Int('/EI=',Mparm_Str);
  3814.     IF (Echo_Interval < 1) THEN
  3815.         Echo_Interval := 9;
  3816.     END;
  3817.  
  3818.     Echo_End := MemP($46C) + Echo_Interval;
  3819.     End_Time := Echo_End + Int_R(Real_I(Timeout) * 18.2);
  3820.     match_index := 1;
  3821.  
  3822. WAIT_LOOP:
  3823.  
  3824.     Error := read_com(port_num,Ch);
  3825.     IF (Error = 0) THEN
  3826.         Display_Str := Display_Str + Ch;
  3827.         IF (Matching) THEN
  3828.             Match_Str := Match_Str + Caps(CH);
  3829.             IF (Match_Str <> Copy(Global_Str('COM_MATCH_STR' + Str(Match_Index)),
  3830.                     1,Svl(Match_Str))) THEN
  3831. {Check to see if any of the other strings match before giving up}
  3832.                 IF (String_Count > 1) THEN
  3833.                     Match_Index := 1;
  3834. LOOK_FOR_OTHER_MATCH:
  3835.                     IF (Match_Str = Copy(Global_Str('COM_MATCH_STR' + Str(Match_Index)),
  3836.                             1,Svl(Match_Str))) THEN
  3837.                         Goto NEW_MATCH;
  3838.                     END;
  3839.                     IF (Match_Index < String_Count) THEN
  3840.                         ++Match_Index;
  3841.                         Goto LOOK_FOR_OTHER_MATCH;
  3842.                     END;
  3843.                 END;
  3844.                 Matching := False;
  3845.                 Goto NEW_MATCH;
  3846.             END;
  3847.             IF (Svl(Match_Str) = Length(Global_Str('COM_MATCH_STR' + Str(Match_Index)))) THEN
  3848.                 Return_Code := Match_Index;
  3849.                 Goto EXIT;
  3850.             END;
  3851.         ELSE
  3852.             Match_Index := 1;
  3853. CHECK_MATCH_BEGIN:
  3854.             IF (Caps(Ch) = Copy(Global_Str('COM_MATCH_STR' + Str(Match_Index)),1,1))
  3855.                 THEN
  3856.                 Match_Str := Caps(Ch);
  3857.                 Matching := True;
  3858.             ELSE
  3859.                 IF (Match_Index < String_Count) THEN
  3860.                     ++Match_Index;
  3861.                     Goto CHECK_MATCH_BEGIN;
  3862.                 END;
  3863.             END;
  3864.         END;
  3865.     END;
  3866. NEW_MATCH:
  3867.     IF (Timeout) THEN
  3868.         IF (MemP($46C) >= End_Time) THEN
  3869.             Return_Code := 0;
  3870.             Goto EXIT;
  3871.         END;
  3872.     END;
  3873.     IF ((Svl(Display_Str) > 200) or (MemP($46C) >= Echo_End)) THEN
  3874.         Echo_End := MemP($46C) + Echo_Interval;
  3875. {
  3876. Beep;
  3877. Write('[' + Match_Str + ']                                          ',1,1,0,Error_Color);
  3878. }
  3879.         RM(Mac_Str + Display_Str);
  3880.         Display_Str := '';
  3881.     END;
  3882.     IF (Key1 = 27) THEN
  3883.         Goto EXIT;
  3884.     END;
  3885.     Check_Key;
  3886.     IF (Key1 = 27) THEN
  3887.         Return_Code := -1;
  3888.         Goto ABORT;
  3889.     END;
  3890.     Goto WAIT_LOOP;
  3891.  
  3892. EXIT:
  3893.     IF (Display_Str <> '') THEN
  3894.         RM(Mac_Str + Display_Str);
  3895.     END;
  3896. ABORT:
  3897.     WHILE (String_Count) DO
  3898.         Set_Global_Str('COM_MATCH_STR' + Str(String_Count),'');
  3899.         --String_Count;
  3900.     END;
  3901.  
  3902.     Return_Int := Return_Code;
  3903. END_MACRO;
  3904.  
  3905. $MACRO COM_SEND_STR;
  3906. {*******************************MULTI-EDIT MACRO*******************************
  3907.  
  3908. Name:    COM_SEND_STR
  3909.  
  3910. Description:    A comunications module macro.  Sends the specified string
  3911.                             to the com port.
  3912.  
  3913. Parameters:
  3914.                     Return_Str = Desired string.
  3915.                     /T=  If 0, timeout is infinite.  If > 0 number of seconds.
  3916.                     /CP=  Character pacing or delay between characters.  Only needed if
  3917.                                 remote is slow.
  3918.  
  3919. Returns:
  3920.  
  3921.                     Return_Int = 1        Successful, string sent.
  3922.                     Return_Int = 0        timeout
  3923.                     Return_Int = -1        aborted by the user pressing <ESC>
  3924.  
  3925.                     Return_Str = string sent (can be useful in case of timeout to
  3926.                                              determine if part of the string was sent).
  3927.  
  3928.                              (C) Copyright 1990 by American Cybernetics, Inc.
  3929. ******************************************************************************}
  3930.     Def_Int(Error,Port_Num,End_Time,Timeout,Pointer,jx,Char_Pacing);
  3931.  
  3932.     Timeout := Parse_Int('/T=',MParm_Str);
  3933.     IF (Timeout < 1) THEN
  3934.         Timeout := 0;
  3935.     END;
  3936.     port_num := global_int('COM_PORT_NUM');
  3937.     Char_Pacing := Parse_Int('/CP=',MParm_Str);
  3938.  
  3939.     Pointer := 0;
  3940.     End_Time := MemP($46C) + Int_R(Real_I(Timeout) * 18.2);
  3941.  
  3942. SEND_LOOP:
  3943.     ++Pointer;
  3944. RETRY:
  3945.     If (Check_Key) THEN
  3946.         IF (Key1 = 27) THEN
  3947.             Return_Int := -1;
  3948.             Goto EXIT;
  3949.         END;
  3950.     END;
  3951.  
  3952.     Delay(Char_Pacing);
  3953.     Error := Write_com(port_num,Copy(Return_Str,Pointer,1),Jx);
  3954.     IF (Pointer >= Length(Return_Str)) THEN
  3955.         Return_Int := 1;
  3956.         Goto EXIT;
  3957.     END;
  3958.     IF (Timeout) THEN
  3959.         IF (MemP($46C) >= End_Time) THEN
  3960.             --Pointer;
  3961.             Return_Int := 0;
  3962.             Goto EXIT;
  3963.         END;
  3964.     END;
  3965.     IF ((Error = 0) and (Jx = 1)) THEN
  3966.         Goto SEND_LOOP;
  3967.     ELSE
  3968.         Goto RETRY;
  3969.     END;
  3970.  
  3971. EXIT:
  3972.  
  3973.     Return_Str := Copy(Return_Str,1,Pointer);
  3974. END_MACRO;
  3975.  
  3976. $MACRO COM_CONNECT_WAIT;
  3977. {*******************************MULTI-EDIT MACRO*******************************
  3978.  
  3979. Name:    COM_CONNECT_WAIT
  3980.  
  3981. Description:    A comunications module macro.  Waits for a connection for a user
  3982. specified time.  Will exit upon timeout or connect, whichever occurs first.  If
  3983. timeout, then it will hang up.  Places a box on the screen to alert user of
  3984. elapsed time.
  3985.  
  3986. Parameters:
  3987.                     /AC= If 1, indicates that we have already made a connection.
  3988.                              Currently, only used when autoredial has already made the
  3989.                              connection.
  3990.  
  3991. Returns:
  3992.                     Return_Int = 0        timeout
  3993.                     Return_Int = 1        connection established
  3994.  
  3995.                              (C) Copyright 1990 by American Cybernetics, Inc.
  3996. ******************************************************************************}
  3997.  
  3998.     Def_Int(Terminator_Index,Temp_Integer,Result_Code,port_num,Box_X,Box_Y);
  3999.     Def_Str(Modem_Response,Temp_Char);
  4000.  
  4001.     Result_Code := False;
  4002.     Box_X := 26;
  4003.     Box_Y := 12;
  4004.     Clr_Vp;
  4005.     Set_Global_Int('Com_Cursor_Pos',$101);
  4006.     port_num := global_int('COM_PORT_NUM');
  4007.     IF (Parse_Int('/AC=',MParm_Str)) THEN
  4008.         Return_Int := True;
  4009.         Goto ALREADY_CONNECTED;
  4010.     END;
  4011.  
  4012. {Use predefined redial timeout spec as a timeout here}
  4013.     Temp_Integer := Parse_Int('/RT=',Global_Str('Com_Modem_Params'));
  4014.     Put_Box(Box_X,Box_Y,Box_X + 28,Box_Y + 3,0,M_B_Color,'WAITING FOR CONNECT',True);
  4015.     Write('Press <ESC> to hang up',Box_X + 3,Box_Y + 2,0,M_B_Color);
  4016. WAIT_FOR_CONNECT:
  4017.     IF (Check_Key) THEN
  4018.         IF (Key1 = 27) THEN
  4019.             Goto EXIT;
  4020.         END;
  4021.     END;
  4022.     Write(Str(Temp_Integer) + ' of ' +
  4023.         Parse_Str('/RT=',Global_Str('Com_Modem_Params')) + ' seconds. ',Box_X + 3,
  4024.         Box_Y + 1,0,M_B_Color);
  4025.     IF (read_com_till(port_num,1,'',Modem_Response,
  4026.         Terminator_Index) = 0) Then
  4027. {This one should be the connect or no connect string}
  4028.  
  4029. MORE_RESPONSE:
  4030.         Delay(50);
  4031.         IF (read_com_till(port_num,80,'|10|13',
  4032.             Temp_Char,Terminator_Index) = 0) THEN
  4033.             Modem_Response := Modem_Response + Temp_Char;
  4034.             IF ((Terminator_Index = 0) and (Svl(Modem_Response) < 80)) THEN
  4035.                 Goto MORE_RESPONSE;
  4036.             END;
  4037.         END;
  4038.         IF (XPos(Parse_Str('/CS=',Global_Str('Com_Modem_Params')),Modem_Response,1)) THEN
  4039.             Result_Code := True;
  4040.             Goto EXIT;
  4041.         END;
  4042.         Goto NOT_CONNECTED;
  4043.     ELSE
  4044. NOT_CONNECTED:
  4045.         IF (Temp_Integer = 0) THEN
  4046.             Goto EXIT;
  4047.         END;
  4048.         Delay(1000);
  4049.         --Temp_Integer;
  4050.         Goto WAIT_FOR_CONNECT;
  4051.     END;
  4052.  
  4053. EXIT:
  4054.     Kill_Box;
  4055.     IF (Result_Code = 0) THEN
  4056. {If unsuccessful, hang up}
  4057.         RM('MECOM^COM_PHONE /TP=3');
  4058.     END;
  4059.     Return_Int := Result_Code;
  4060. ALREADY_CONNECTED:
  4061. END_MACRO;
  4062.  
  4063. $MACRO COM_CURSOR_OFF;
  4064. {*******************************MULTI-EDIT MACRO*******************************
  4065.  
  4066. Name:    COM_CURSOR_OFF
  4067.  
  4068. Description:    A comunications module macro.  Turns the cursor off.
  4069.  
  4070.                              (C) Copyright 1990 by American Cybernetics, Inc.
  4071. ******************************************************************************}
  4072. {Use the BIOS interrupt $10}
  4073.     R_AX := $0100;
  4074.     R_CX := $2000;
  4075.     Intr($10);
  4076. END_MACRO;
  4077.  
  4078. $MACRO COM_CURSOR_ON;
  4079. {*******************************MULTI-EDIT MACRO*******************************
  4080.  
  4081. Name:    CURSOR_ON
  4082.  
  4083. Description:    A comunications module macro.  Turns the cursor on.
  4084.  
  4085.                              (C) Copyright 1990 by American Cybernetics, Inc.
  4086. ******************************************************************************}
  4087. {Any reference to the system variable INSERT_MODE will reset the cursor}
  4088.     INSERT_MODE := INSERT_MODE;
  4089. END_MACRO;
  4090.  
  4091. $MACRO COM_SCREEN_DUMP;
  4092. {*******************************MULTI-EDIT MACRO*******************************
  4093.  
  4094. Name:    COM_SCREEN_DUMP
  4095.  
  4096. Description:    A comunications module macro.  Captures the terminal screen to
  4097.                             a file or device.
  4098.  
  4099. Parameters:
  4100.                             /MY= The Y coordinate to reference the prompt box to.
  4101.  
  4102.                              (C) Copyright 1990 by American Cybernetics, Inc.
  4103. ******************************************************************************}
  4104.     Def_Int(Line_Counter,Column_Counter,Active_Page,Old_x,old_y,Menu_Y,Handle,
  4105.                     Error);
  4106.     Def_Str(T_Str,Sstr[10]);
  4107.     Menu_Y := Parse_Int('MY=',MParm_Str);
  4108.     IF (Menu_Y < 1) THEN
  4109.         Menu_Y := 3;
  4110.     END;
  4111.  
  4112.     sstr := ' /S=1';
  4113.     Return_Str := 'MECOM.SCR';
  4114.  
  4115. PROMPT:
  4116.     RM('USERIN^QUERYBOX /C=16/W=12/H=MECOM^*/T=SCREEN CAPTURE FILE NAME/L=' + Str(Menu_Y + 7));
  4117.     IF (RETURN_INT) THEN
  4118.         IF (Return_Str = '') THEN
  4119.             Beep;
  4120.             Goto PROMPT;
  4121.         END;
  4122.  
  4123.         IF (File_Exists(Return_Str)) THEN
  4124. {Check to see if the file is a device like a printer.  If so, don't bother
  4125. with the menu that follows.}
  4126.             Error := S_Open_File(Return_Str,1,Handle);
  4127.             IF (Error) THEN
  4128.                 Error_Level := 3000 + Error;
  4129.                 RM('MEERROR');
  4130.                 Goto EXIT;
  4131.             END;
  4132.             R_AX := $4400;
  4133.             R_BX := Handle;
  4134.             Intr($21);
  4135.             IF (R_Flags and $01) THEN
  4136.                 Error_Level := 3000 + R_AX;
  4137.                 RM('MEERROR');
  4138.                 Goto ABORT;
  4139.             END;
  4140.             Line_Counter := R_DX;
  4141.             Error := S_Close_File(handle);
  4142.             IF (Error) THEN
  4143.                 Error_Level := 3000 + Error;
  4144.                 RM('MEERROR');
  4145.                 Goto EXIT;
  4146.             END;
  4147.             IF (Line_Counter and $80) THEN
  4148.                 Goto NEW_FILE;
  4149.             END;
  4150.             RM('USERIN^XMENU /B=1/T=1/X=16/Y=' + Str(Menu_Y + 7) +
  4151.                                 '/S=1/L=SCREEN CAPTURE FILE EXISTS' +
  4152.                                 '/M=Append(MECOM^*)Overwrite()aBort()');
  4153.             IF ((Return_Int < 1) or (Return_Int = 3)) THEN
  4154.                 Goto EXIT;
  4155.             END;
  4156.             IF (Return_Int = 1) THEN
  4157.                 Error := S_Open_File(Return_Str,1,Handle);
  4158.                 IF (Error) THEN
  4159.                     Error_Level := 3000 + Error;
  4160.                     RM('MEERROR');
  4161.                     Goto EXIT;
  4162.                 END;
  4163.                 Error := S_Move_File_Ptr(Handle,2,0);
  4164.                 IF (Error) THEN
  4165.                     Error_Level := 3000 + Error;
  4166.                     RM('MEERROR');
  4167.                     Goto ABORT;
  4168.                 END;
  4169.                 Goto APPEND_FILE;
  4170.             END;
  4171.             IF (Return_Int = 2) THEN
  4172.                 Goto NEW_FILE;
  4173.             END;
  4174.         ELSE
  4175. NEW_FILE:
  4176.             Error := S_Create_File(Return_Str,Handle);
  4177.             IF (Error) THEN
  4178.                 Error_Level := 3000 + Error;
  4179.                 RM('MEERROR');
  4180.                 Goto EXIT;
  4181.             END;
  4182.         END;
  4183.     ELSE
  4184.         Goto EXIT;
  4185.     END;
  4186. APPEND_FILE:
  4187.  
  4188.     old_x := WhereX_vp;
  4189.     old_y := whereY_vp;
  4190.     Line_Counter := 0;
  4191.     Column_Counter := 0;
  4192.     T_Str := '';
  4193.     R_AX := $0F00;
  4194.     Intr($10);
  4195.     Active_Page := R_BX;
  4196.  
  4197.     WHILE (Line_Counter < Screen_Length) DO
  4198.         ++Line_Counter;
  4199.         Column_Counter := 0;
  4200.         T_Str := '';
  4201.  
  4202. {Get the screen a line at a time}
  4203.         WHILE (Column_Counter < Screen_Width) DO
  4204.             ++Column_Counter;
  4205. {Get the character at the cursor}
  4206.             GotoXY_VP(Column_Counter,Line_Counter);
  4207.             R_AX := $0800;
  4208.             R_BX := Active_Page;
  4209.             Intr($10);
  4210.             T_Str := T_Str + Char(R_AX and $FF);
  4211.         END;
  4212.  
  4213. {Send line to file or device}
  4214.         Return_Str := t_str + '|13|10';
  4215.         RM('MEUTIL3^PRINTSTR' + sstr + '/H=' + Str(Handle));
  4216.         sstr := ' ';
  4217.         IF (Error_Level) THEN
  4218.             RM('MEERROR');
  4219.             Goto ABORT;
  4220.         END;
  4221.     END;
  4222.  
  4223.     Gotoxy_vp(old_x,old_y);
  4224.  
  4225. ABORT:
  4226.  
  4227.     Error := S_Close_File(handle);
  4228.  
  4229. EXIT:
  4230.  
  4231. END_MACRO;
  4232.  
  4233. $MACRO COM_SEND_MSG;
  4234. {*******************************MULTI-EDIT MACRO*******************************
  4235.  
  4236. Name:    COM_SEND_MSG
  4237.  
  4238. Description:    A comunications module macro.  Creates a window to edit a message
  4239.                             to send to the com port.  Very useful if you don't like the EMail
  4240.                             editing system on the BBS you're using.  Both spell checking and
  4241.                             search are enabled.
  4242.  
  4243.                              (C) Copyright 1990 by American Cybernetics, Inc.
  4244. ******************************************************************************}
  4245.     Def_Int(Active_Window,Wrap,Margin);
  4246.  
  4247.     Active_Window := Window_Id;
  4248.     Create_Window;
  4249.     File_Name := 'MECOM.MSG';
  4250.     File_Changed := False;
  4251.     Wrap := Parse_Int('/MWW=',Global_Str('COM_GENERAL_PARAMS'));
  4252.     Margin := Parse_Int('/MRM=',Global_Str('COM_GENERAL_PARAMS'));
  4253.  
  4254. {The macro EDITWINDOW provides the editor like interface}
  4255.     RM('USERIN^EDITWINDOW /H=MECOM^ME/X=1/SE=1/RM=74/SP=1/T=CREATE A MESSAGE TO SEND TO THE COM PORT/Y='
  4256.             + Str(Min_Window_Row) + '/W=' + Str(Screen_Width) + '/L=' +
  4257.             Str(Max_Window_Row - Min_Window_Row - 2) + '/WW=' + Str(Wrap) + '/RM=' +
  4258.             Str(Margin));
  4259.     IF (File_Changed) THEN
  4260.         RM('userin^VERIFY /H=MECOM^ME/L=10/C=10/S=2/H=MECOM^*/T=SEND THIS MESSAGE TO THE COM PORT?');
  4261.         IF (Return_Int) THEN
  4262.             Tof;
  4263.             WHILE (Not(At_Eof)) DO
  4264. {Send each line to the com port adding EOL terminator, character pacing, and
  4265.  blank line expansion as configured by user}
  4266.                 IF ((Get_Line = '') and
  4267.                         (Parse_Int('/S=',Global_Str('Com_Ascii_Params')) > 0)) THEN
  4268.                     Return_Str := ' ';
  4269.                 ELSE
  4270.                     Return_Str := '';
  4271.                 END;
  4272.                 Return_Str := Return_Str + Get_Line + Copy('|13|10',1,Parse_Int('/CO=',
  4273.                     Global_Str('COM_TERMINAL_PARAMS')) + 1);
  4274.  
  4275.                 RM('MECOM^COM_SEND_STR /T=10/CP=' + Parse_Str('/CP=',Global_Str('Com_Ascii_Params')));
  4276. {Look and see if there are any incomming characters to display}
  4277.                 RM('MECOM^COM_WAIT_FOR_STR /T=1/EI=9');
  4278.                 Down;
  4279.             END;
  4280.         END;
  4281.     END;
  4282.  
  4283.     Delete_Window;
  4284.     IF (Switch_Win_Id(Active_Window)) THEN END;
  4285. END_MACRO;
  4286.  
  4287. $MACRO COM_VIEW_FILE;
  4288. {*******************************MULTI-EDIT MACRO*******************************
  4289.  
  4290. Name:    COM_VIEW_FILE
  4291.  
  4292. Description:    A comunications module macro.  Creates a window to view and edit
  4293.                             a file or the currently active log.  In the case of the log, it
  4294.                             can serve as an enhanced "scroll back" feature.
  4295.  
  4296.                              (C) Copyright 1990 by American Cybernetics, Inc.
  4297. ******************************************************************************}
  4298.  
  4299.     Def_Int(Active_Window,View_Window,Log_Handle,Bytes_Written,Error,Menu_Y,
  4300.                     Viewing_Log,TBC,Already_Viewed,Wrap,Margin);
  4301.     Def_Str(F_Name[40]);
  4302.  
  4303.     Menu_Y := Parse_Int('MY=',MParm_Str);
  4304.     Viewing_Log := False;
  4305.     TBC := Box_Count;
  4306.     View_Window := 0;
  4307.     Wrap := Parse_Int('/VWW=',Global_Str('COM_GENERAL_PARAMS'));
  4308.     Margin := Parse_Int('/VRM=',Global_Str('COM_GENERAL_PARAMS'));
  4309.  
  4310.     IF ((Global_Int('Com_Logging') = True) and
  4311.         (Parse_Int('/LOG=',MParm_Str) = True)) THEN
  4312. {Need to close the log file so we can load it into the window.}
  4313.         Error := S_Write_Bytes(Global_Str('Com_Log_Str'),Global_Int('Com_Log_Handle'),Bytes_Written);
  4314.         IF (Bytes_Written < Length(Global_Str('Com_Log_Str'))) THEN
  4315.             Return_Int := 3241;
  4316.             RM('COM_LOG_ERROR');
  4317.             Goto ABORT;
  4318.         END;
  4319.         IF (Error) THEN
  4320.             Return_Int := Error;
  4321.             RM('COM_LOG_ERROR');
  4322.             Goto ABORT;
  4323.         END;
  4324.         Error := S_Close_File(Global_Int('Com_Log_Handle'));
  4325.         IF (Error) THEN
  4326.             Return_Int := Error;
  4327.             RM('COM_LOG_ERROR');
  4328.             Goto ABORT;
  4329.         END;
  4330.         Set_Global_Int('Com_Logging',False);
  4331.         Set_Global_Str('Com_Log_Str','');
  4332.         Viewing_Log := True;
  4333. {Word wrap is probably not desirable when viewing the log}
  4334.         Wrap := 0;
  4335.         Margin := 0;
  4336.     END;
  4337.  
  4338.  
  4339.     Active_Window := Window_Id;
  4340.     Create_Window;
  4341.     View_Window := Window_Id;
  4342.  
  4343.  
  4344. {Load the file.}
  4345.     IF (Viewing_Log) THEN
  4346.         Return_Str := Global_Str('COM_LOG_FILE');
  4347.     ELSE
  4348.         Return_Str := '';
  4349. LOAD_PROMPT:
  4350.         RM('USERIN^QUERYBOX /H=MECOM^FILVIE/C=16/W=40/T=FILE TO VIEW/F2=Dir   /L=' +
  4351.                 Str(Menu_Y + 9 + (Global_Int('Com_LOGGING') * 3)));
  4352.  
  4353.         IF (Return_Int = 0) THEN
  4354.             Goto ABORT;
  4355.         END;
  4356.         IF (Return_Int = -1) THEN
  4357.             refresh := true;
  4358.             fkey_row := Global_Int('Temp_fkey_row');
  4359. {
  4360.             Message_Row := Global_Int('Temp_Message_Row');
  4361. }
  4362.             RM('DIRSHELL /S=1');
  4363.             fkey_row := 0;
  4364. {
  4365.             Message_Row := 0;
  4366. }
  4367.             Set_Vp(Parse_Int('/X1=',Global_Str('Com_Cur_Scrn_Params')) + 1,
  4368.                 Parse_Int('/Y1=',Global_Str('Com_Cur_Scrn_Params')) + 1,
  4369.                 Parse_Int('/X2=',Global_Str('Com_Cur_Scrn_Params')) - 1,
  4370.                 Parse_Int('/Y2=',Global_Str('Com_Cur_Scrn_Params')) - 1);
  4371.                 Text_Color_Vp := Parse_Int('/F=',Global_Str('Com_Color_Params')) +
  4372.                                             (Parse_Int('/B=',Global_Str('Com_Color_Params')) shl 4);
  4373.             refresh := false;
  4374.             If Return_Str <> '' THEN
  4375.                 Goto LOAD_PROMPT;
  4376.             END;
  4377.         END;
  4378.     END;
  4379.  
  4380.     Load_File(Return_Str);
  4381.     IF (Error_Level) THEN
  4382.         RM('MEERROR');
  4383.         Error_Level := 0;
  4384.         Return_Str := '';
  4385.         Goto LOAD_PROMPT;
  4386.     END;
  4387.     F_Name := Caps(Return_Str);
  4388.     IF (Viewing_Log) THEN
  4389.         Eof;
  4390.         Goto_Col(1);
  4391.     END;
  4392.     Already_Viewed := False;
  4393. VIEW_FILE:
  4394.     RM('USERIN^EDITWINDOW /H=MECOM^FILVIE/X=1/CC=1/SE=1/NK=1/Y=' + Str(Min_Window_Row) + '/W=' +
  4395.             Str(Screen_Width) + '/L=' +    Str(Max_Window_Row - Min_Window_Row - 2) +
  4396.             '/NB=' + Str(Already_Viewed) + '/WW=' + Str(Wrap) + '/RM=' + Str(Margin) +
  4397.             '/T=VIEWING' + copy(' LOG ',1,(Viewing_Log * 4) + 1) + 'FILE: ' + F_Name);
  4398.     Already_Viewed := True;
  4399. {If they altered the file, give them a chance to save.}
  4400.     Read_Only := False;
  4401.     RM('WINDOW^DELWIN /BC=' + Str(Box_Count));
  4402.     IF (Return_Int = 0) THEN
  4403. {If they said don't exit yet, put em back into the editwindow}
  4404.         Goto VIEW_FILE;
  4405.     END;
  4406.  
  4407.     IF (Viewing_Log) THEN
  4408. {Now, reopen the log for append and move the file pointer.}
  4409.         Error := S_Open_File(Global_Str('COM_LOG_FILE'),1,Log_Handle);
  4410.         IF (Error) THEN
  4411.             Return_Int := Error;
  4412.             RM('MECOM^COM_LOG_ERROR');
  4413.             Goto ABORT;
  4414.  
  4415.         END;
  4416.         Error := S_Move_File_Ptr(Log_Handle,2,0);
  4417.         IF (Error) THEN
  4418.             Return_Int := Error;
  4419.             RM('MECOM^COM_LOG_ERROR');
  4420.             Goto ABORT;
  4421.         END;
  4422.  
  4423.     {Set the log handle global to new handle.}
  4424.         Set_Global_Int('Com_LOG_Handle',Log_Handle);
  4425.         Set_Global_Int('Com_LOGGING',True);
  4426.  
  4427.     END;
  4428.  
  4429. ABORT:
  4430.     IF (Switch_Win_Id(View_Window)) THEN
  4431.         Read_Only := False;
  4432.         Delete_Window;
  4433.     END;
  4434.     IF (Switch_Win_Id(Active_Window)) THEN END;
  4435. EXIT:
  4436. {Kill any remaining boxes made during the running of this macro}
  4437.     WHILE (Box_Count > TBC) DO
  4438.         Kill_Box;
  4439.     END;
  4440. END_MACRO;
  4441.