home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / control / icom20a / icom.c next >
Text File  |  1990-05-22  |  26KB  |  1,171 lines

  1. /*
  2.  
  3.     ICOM Radio Control Program
  4.         (generalized ICOM)
  5.  
  6.     written in TURBO C V1.5
  7.  
  8.     by John Lundy - N5MHZ
  9.  
  10.  
  11.             **  NOTE  **
  12.  
  13.     If you make modifications to this program and compile and link it, be
  14.     sure and convert the .EXE file to .COM!  Although this program may
  15.     work in some .EXE configurations, it cannot be guaranteed.  So, be safe
  16.     and use EXE2BIN to convert it...
  17.  
  18. */
  19. #include <bios.h>
  20. #include <conio.h>
  21. #include <ctype.h>
  22. #include <dos.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #define REV  "2.0"
  28.  
  29. #define BUF_SZ 4096
  30. #define TMR_VEC 0x1c
  31. #define COM_VEC 0x0c
  32. #define KBD_VEC 0x09
  33.  
  34. #undef pokeb
  35. #undef peekb
  36. #undef poke
  37. #undef peek
  38. #define pokeb(s,o,b) (*((unsigned char far *)(((long)(s)<<16)+(o)))) = (b)
  39. #define peekb(s,o) (*((unsigned char far *)(((long)(s)<<16)+(o))))
  40. #define poke(s,o,w) (*((unsigned int far *)(((long)(s)<<16)+(o)))) = (w)
  41. #define peek(s,o) (*((unsigned int far *)(((long)(s)<<16)+(o))))
  42.  
  43. struct    text_info    dos_info;
  44.  
  45. char    auth[]="John Lundy - N5MHZ";
  46.  
  47. unsigned char    ch, cn, first[BUF_SZ];
  48. unsigned char    *get, *put, *last = &first[BUF_SZ-1];
  49. unsigned char    dscr[25][160];
  50. unsigned char    tx[81], cmd[17], dat[33], fn[81], drv[3], dir[65];
  51. char    hex[17]={"0123456789ABCDEF"};
  52. char    bds[64][73];
  53. unsigned int    ticks=0, tacks=0;
  54. unsigned int    d_ss, d_sp, sss, ssp, ssn, ssv[64];
  55. int        i, j, k, x, y, dx, dy, vx, vy, tvx, tvy;
  56. int        addr, com;
  57. int        com_base, thr, rbr, llsb, lmsb, ier, iir, lcr, mcr, lsr, msr;
  58. int        bits, baud, paron, parity, stops, intrpt;
  59. int        bdiv, blsb, bmsb, cctl;
  60. int        ptx, active=1, slct=0, rq, rqf;
  61. int        dds, fgd, bgd;
  62. int        m, v, c, bp=-1, tp, ud, bm, bms=0, bf=0, tv=0, td=4, flh=0;
  63. long    l, r;
  64. long    f, fb, ft, fi=250;
  65. long    fl[32], fh[32];
  66. long    bdf[64];
  67. int        bdm[64];
  68. int        *parm[]={    &addr,&com,&bits,&baud,&stops,
  69.                     &paron,&parity,&intrpt,&fgd,&bgd,
  70.                     NULL};
  71.  
  72. char    *ptxt[]={   "ICOM address (decimal) %2d\r\n",
  73.                     "Com port                %1d\r\n",
  74.                     "Data bits               %1d\r\n",
  75.                     "Baud rate           %05d\r\n",
  76.                     "Stop bit(s)             %1d\r\n",
  77.                     "Parity on=1/off=0       %1d\r\n",
  78.                     "Parity odd=1/even=0     %1d\r\n",
  79.                     "Interrupt               %1d\r\n",
  80.                     "Foreground color       %02d\r\n",
  81.                     "Background color        %1d\r\n",NULL};
  82.  
  83. int        aptr[]={4,4,4,4,4,4,2,2,4,2,2,4};
  84.  
  85. char    *prgm[]={    "03E000FEFE",    /* Freq */
  86.                     "04E000FEFE",    /* Mode */
  87.                     "09E000FEFE",    /* Mem  */
  88.                     "0AE000FEFE",    /* Mem->VFO */
  89.                     "07E000FEFE",    /* VFO  */
  90.                     "08E000FEFE",    /* Chan */
  91.                     "000000FEFE",    /* Freq */
  92.                     "0300E0FEFE",
  93.                     "05E000FEFE",
  94.                     "010000FEFE",    /* Mode */
  95.                     "0400E0FEFE",
  96.                     "06E000FEFE",
  97.                     NULL};
  98.  
  99. /*
  100.             **  NOTE  **
  101.  
  102.     Use extreme care if you compile this program using
  103.     any other version of C.  The following reference to
  104.     to _atexittbl is to determine the highest address used
  105.     by our program.  In TURBO C this location in memory is
  106.     the address of a 64 byte block of data storage that is
  107.     always the highest referenced address of a TURBO C pro-
  108.     gram.
  109. */
  110. void _atexittbl (void);
  111.  
  112. void interrupt (*oldtmr)();
  113. void interrupt (*oldcom)();
  114. FILE    *stream;
  115.  
  116. /*************************/
  117. /*  Sound Initializaton  */
  118. /*************************/
  119. void bgnsd(long snd)
  120. {
  121.     snd = 1193280 / snd;
  122.     outportb(0x43,0xb6);
  123.     outportb(0x42,(char) (snd & 0xff));
  124.     outportb(0x42,(char) ((snd >> 8) & 0xff));
  125.     outportb(0x61,inportb(0x61) | 3);
  126.     return;
  127. }
  128.  
  129. /***********************/
  130. /*  Sound Termination  */
  131. /***********************/
  132. void endsd(void)
  133. {
  134.     outportb(0x61,inportb(0x61) & 0xfc);
  135.     return;
  136. }
  137.  
  138. /*********************/
  139. /*  Com Int Handler  */
  140. /*********************/
  141. void interrupt newcom()
  142. {
  143.     if (active)
  144.     {
  145.         outportb(0x20,0x60 + intrpt);    /*    EOI    */
  146.         switch (inportb(iir))
  147.         {
  148.         case 6:
  149.             break;
  150.         case 4:
  151.             *put++ = inportb(rbr);
  152.             if (put == last) put = first;
  153.             break;
  154.         case 2:
  155.             break;
  156.         case 0:
  157.             break;
  158.         default:
  159.             break;
  160.         }
  161.     }
  162.     else
  163.     {
  164.         (*oldcom)();
  165.     }
  166.     return;
  167. }
  168.  
  169. /***********************/
  170. /*  Timer Int Handler  */
  171. /***********************/
  172. void interrupt newtmr()
  173. {
  174.     (*oldtmr)();
  175.     if (slct == 0) if ((peekb(0x40, 0x17) & 0xf) == 5) slct = 1;
  176.     if (active)
  177.     {
  178.         if (ticks == 2) bgnsd(400); else if (ticks == 1) endsd();
  179.         if (ticks) ticks--; if (tacks) tacks--;
  180.     }
  181.     else
  182.     {
  183.         if (slct) if ((peekb(0x40, 0x17) & 0xf) == 0)
  184.         {
  185.             disable(); outportb(0x20,0x60); active = 1; slct = 0;
  186.             d_ss = _SS; d_sp = _SP; _SS = sss; _SP = ssp;
  187.             ssn = 0x8000 - (d_sp / 2);
  188.             if (ssn > 64) ssn = 64;
  189.             for (i=0 ; i < ssn ; i++) ssv[i] = peek(d_ss, d_sp + i * 2);
  190.             enable(); prog(); disable();
  191.             for (i=0 ; i < ssn ; i++) poke(d_ss, d_sp + i * 2, ssv[i]);
  192.             _SS = d_ss; _SP = d_sp; active = slct = 0;
  193.         }
  194.     }
  195.     return;
  196. }
  197.  
  198. /***********************/
  199. /*  Transmit Character */
  200. /***********************/
  201. void xmtch(unsigned char ch)
  202. {
  203.     while ((inportb(lsr) & 0x20) == 0);
  204.     outportb(thr,ch);
  205.     return;
  206. }
  207.  
  208. /*********************/
  209. /*  Transmit String  */
  210. /*********************/
  211. void xmts(char *strg)
  212. {
  213.     while (*strg) xmtch(*strg++);
  214.     return;
  215. }
  216.  
  217. /*******************/
  218. /*  Setup Com Port */
  219. /*******************/
  220. void set_com(void)
  221. {
  222.     com_base = peek(0x40,(com - 1) * 2);
  223.     thr = com_base;
  224.     rbr = com_base;
  225.     llsb = com_base;
  226.     lmsb = com_base + 1;
  227.     ier = com_base + 1;
  228.     iir = com_base + 2;
  229.     lcr = com_base + 3;
  230.     mcr = com_base + 4;
  231.     lsr = com_base + 5;
  232.     msr = com_base + 6;
  233.  
  234.     /*
  235.         Establish baud rate divisor
  236.     */
  237.     bdiv = 115200 / baud;
  238.     blsb = bdiv & 0xff;
  239.     bmsb = (bdiv >> 8) & 0xff;
  240.  
  241.     /*
  242.         Establish character attributes
  243.     */
  244.     cctl = (bits - 5) + ((stops - 1) << 2) + (paron << 3) + ((1 - parity) << 5);
  245.  
  246.     /*
  247.         Initialize COM port
  248.     */
  249.     outportb(ier,0x00);        /* Disable Interrupts         */
  250.     outportb(lcr,0x80|cctl);/* Attributes & Set Baud      */
  251.     outportb(llsb,blsb);    /* LSB of Divisor for Baud    */
  252.     outportb(lmsb,bmsb);    /* MSB of Divisor for Baud    */
  253.     outportb(lcr,cctl);        /* Attributes & Xmt Regs Enab */
  254.     outportb(mcr,0x0b);        /* DTR/RTS & Enable Int       */
  255.     outportb(ier,0x01);        /* Enable Int on Rcv Data     */
  256.     inportb(lsr);            /* Clr Line Status Reg        */
  257.     inportb(msr);            /* Clr Modem Status Reg       */
  258.     inportb(rbr);            /* Clr Receive Buffer Reg     */
  259.     inportb(iir);            /* Clr Int Ident Reg          */
  260.     outportb(0x21,inportb(0x21) & (~(1 << intrpt)));
  261.     return;
  262. }
  263.  
  264. /*****************************/
  265. /*  Reset Interrupt Vectors  */
  266. /*****************************/
  267. void rst_vect(void)
  268. {
  269.     /*
  270.         Deassign interrupt vectors
  271.     */
  272.     outportb(0x21,inportb(0x21) | (1 << intrpt));
  273.     setvect(COM_VEC - (1 - (com & 1)), oldcom);
  274.     setvect(TMR_VEC, oldtmr);
  275.     return;
  276. }
  277.  
  278. /********************/
  279. /*  Write to Radio  */
  280. /********************/
  281. void wrt(void)
  282. {
  283.     ticks = 9 * rq;
  284.     xmtch(0xfe); xmtch(0xfe);
  285.     xmtch(addr); xmtch(0xe0);
  286.     xmtch(cn);
  287.     for (i=0 ; i < dat[0] ; xmtch(dat[++i]));
  288.     xmtch(0xfd);
  289.     return;
  290. }
  291.  
  292. /********************/
  293. /*  Read Frequency  */
  294. /********************/
  295. void rd_freq(void)
  296. {
  297.     cn = 3; rq = 2;
  298.     dat[0] = 0;
  299.     wrt();
  300.     return;
  301. }
  302.  
  303. /***************/
  304. /*  Read Mode  */
  305. /***************/
  306. void rd_mode(void)
  307. {
  308.     cn = 4; rq = 2;
  309.     dat[0] = 0;
  310.     wrt();
  311.     return;
  312. }
  313.  
  314. /*********************/
  315. /*  Write Frequency  */
  316. /*********************/
  317. void wr_freq(void)
  318. {
  319.     cn = 5; rq = 2;
  320.     sprintf(tx,"%010ld",f);
  321.     dat[0] = fb / 2;
  322.     for (i=10-fb, j=fb/2 ; i < 10 ; i+=2, j--)
  323.         dat[j] = ((tx[i] - '0') << 4) + (tx[i+1] - '0');
  324.     wrt();
  325.     return;
  326. }
  327.  
  328. /****************/
  329. /*  Write Mode  */
  330. /****************/
  331. void wr_mode(void)
  332. {
  333.     cn = 6; rq = 2;
  334.     dat[1] = m;
  335.     dat[0] = 1;
  336.     wrt();
  337.     return;
  338. }
  339.  
  340. /***************/
  341. /*  Write VFO  */
  342. /***************/
  343. void wr_vfo(void)
  344. {
  345.     cn = 7; rq = 2;
  346.     dat[1] = v;
  347.     dat[0] = 1;
  348.     wrt();
  349.     return;
  350. }
  351.  
  352. /*******************/
  353. /*  Write Channel  */
  354. /*******************/
  355. void wr_ch(void)
  356. {
  357.     cn = 8; rq = 2;
  358.     if (c < 10)
  359.         dat[1] = c;
  360.     else
  361.         dat[1] = ((c / 10) << 4) + (c - ((c / 10) * 10));
  362.     dat[0] = 1;
  363.     wrt();
  364.     return;
  365. }
  366.  
  367. /******************/
  368. /*  Write Memory  */
  369. /*****************/
  370. void wr_tmem(void)
  371. {
  372.     cn = 9; rq = 2;
  373.     dat[0] = 0;
  374.     wrt();
  375.     return;
  376. }
  377.  
  378. /***************/
  379. /*  Write VFO  */
  380. /***************/
  381. void wr_tvfo(void)
  382. {
  383.     cn = 10; rq = 2;
  384.     dat[0] = 0;
  385.     wrt();
  386.     return;
  387. }
  388.  
  389. /*********************/
  390. /*  Print Frequency  */
  391. /*********************/
  392. void pfreq(void)
  393. {
  394.     gotoxy(1,23);
  395.     l = f / 1000l;
  396.     r = (f - (l * 1000l)) / 10l;
  397.     cprintf("%7ld.%02ld KHz in",l,r);
  398.     gotoxy(1,1);
  399.     if (bp >= 0)
  400.         if ((f >= fl[bp]) && (f <= fh[bp])) return;
  401.     for (bp=0 ; bp < flh ; bp++) if ((f >= fl[bp]) && (f <= fh[bp])) return;
  402.     bp = -1;
  403.     return;
  404. }
  405.  
  406. /****************/
  407. /*  Print Mode  */
  408. /****************/
  409. void pmode(void)
  410. {
  411.     gotoxy(19,23);
  412.     switch (m)
  413.     {
  414.     case 0:    strcpy(tx,"LSB "); break;
  415.     case 1:    strcpy(tx,"USB "); break;
  416.     case 2:    strcpy(tx," AM "); break;
  417.     case 3:    strcpy(tx," CW "); break;
  418.     case 4: strcpy(tx,"RTTY"); break;
  419.     case 5:    strcpy(tx," FM "); break;
  420.     default:    strcpy(tx,"UNKN"); break;
  421.     }
  422.     cprintf("%4s mode",tx);
  423.     gotoxy(1,1);
  424.     return;
  425. }
  426.  
  427. /***************/
  428. /*  Print VFO  */
  429. /***************/
  430. void pvfo(void)
  431. {
  432.     gotoxy(29,23);
  433.     switch (v)
  434.     {
  435.     case 0:    strcpy(tx,"Vfo A"); break;
  436.     case 1:    strcpy(tx,"Vfo B"); break;
  437.     default:    strcpy(tx,"Vfo ?"); break;
  438.     }
  439.     cprintf("%s",tx);
  440.        rd_freq();
  441.     rqf = 1;
  442.     return;
  443. }
  444.  
  445. /****************/
  446. /*  Print Chan  */
  447. /****************/
  448. void pchn(void)
  449. {
  450.     gotoxy(35,23);
  451.     cprintf("Chan %2d",c);
  452.     gotoxy(1,1);
  453.     return;
  454. }
  455.  
  456. /********************/
  457. /*  Refresh Screen  */
  458. /********************/
  459. void ref_scrn(void)
  460. {
  461.     textcolor(fgd); textbackground(bgd);
  462.     clrscr(); gotoxy(2,1);
  463.     cprintf("ICOM Programmer  Version %s  %s  %s\r\n\r\n",REV,__DATE__,__TIME__);
  464.     gotoxy(1,4);
  465.     cprintf("B/T-Band Bot/Top    F-Frequency         (Band/Mode Entries) \r\n");
  466.     cprintf("P/N-Band Prv/Nxt    .-Round Freq        Ins-Store           \r\n");
  467.     cprintf("                                        Del-Clear           \r\n");
  468.     cprintf("D/U-Scan Down/Up    C-Memory Channel    -> -Next            \r\n");
  469.     cprintf("I-Scan Increment    V-Memory->Vfo       <- -Prev            \r\n");
  470.     cprintf("                    M-Vfo->Memory       R-Recall Last Entry \r\n");
  471.     cprintf("                                        L-Load List Disk    \r\n");
  472.     cprintf("Ctrl/RShift-Exit                        S-Save List Disk    \r\n");
  473.     cprintf("                                        Z-Clear List        \r\n");
  474.     cprintf("                    (Key Pad)                               \r\n");
  475.     cprintf("Home +Scan Incr     Up   +.1 KHz        PgUp +1 KHz         \r\n");
  476.     cprintf("Left -.5 KHz                            Rght +.5 KHz        \r\n");
  477.     cprintf("End  -Scan Incr     Down -.1 KHz        PgDn -1 KHz         \r\n");
  478.     gotoxy(2,25);
  479.     textcolor(bgd); textbackground(fgd);
  480.     cprintf(" F1-LSB  F2-USB  F3-AM  F4-CW  F5-RTTY  F6-FM  F7-VfoA  F8-VfoB               ");
  481.     textcolor(fgd); textbackground(bgd);
  482.     set_com();
  483.        rd_freq();
  484.     rqf = 1;
  485.     return;
  486. }
  487.  
  488. /**************************/
  489. /*  Convert Text to Long  */
  490. /**************************/
  491. long cnv_txt(char *tx)
  492. {
  493.     for (i=0 ; (tx[i] == ' ') || (tx[i] == 0x9) ; i++);
  494.     if ((tx[i] == '-') || (tx[i] == '+')) j = i + 1; else j = i;
  495.     for (l=0 ; isdigit(tx[j]) ; j++)
  496.         l = l * 10 + (tx[j] - '0');
  497.     if (tx[j] == '.') j++;
  498.     for (k=0, r=0 ; isdigit(tx[j]) && (k < 2) ; j++, k++)
  499.         r = r * 10 + (tx[j] - '0');
  500.     for ( ; k < 3 ; k++) r *= 10;
  501.     ft = l * 1000l + r;
  502.     return(ft);
  503. }
  504.  
  505. /*********************/
  506. /*  Load Parameters  */
  507. /*********************/
  508. int ld_parm(void)
  509. {
  510.     stream = fopen(fn,"rb");
  511.     if (stream != NULL)
  512.     {
  513.         do
  514.         {
  515.             if (fgets(tx,81,stream) == NULL) break;
  516.             for(j=strlen(tx) ; (j > 0) && (isdigit(tx[j]) == 0) ; j--);
  517.             for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  518.                addr = atoi(&tx[j]);
  519.             break;
  520.         }
  521.         while (-1);
  522.         flh = 0;
  523.         do
  524.         {
  525.             if (fgets(tx,81,stream) == NULL) break;
  526.             if (tx[0] != '*') break;
  527.             if (flh < 32)
  528.             {
  529.                 for(j=strlen(tx) ; (j > 0) && (isdigit(tx[j]) == 0) ; j--);
  530.                 for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  531.                 fh[flh] = atol(&tx[j]);
  532.                 for( ; (j > 0) && isspace(tx[j]) ; j--);
  533.                 tx[j+1] = 0;
  534.                 for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  535.                 if (tx[j] != '*')
  536.                     fl[flh] = atol(&tx[j]);
  537.                 else
  538.                     fl[flh] = atol(&tx[j+1]);
  539.                 flh++;
  540.             }
  541.         }
  542.         while (-1);
  543.         for (i=1 ; parm[i] != NULL ; i++)
  544.         {
  545.             if (feof(stream)) break;
  546.             for(j=strlen(tx) ; (j > 0) && (isdigit(tx[j]) == 0) ; j--);
  547.             for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  548.                *parm[i] = atoi(&tx[j]);
  549.             fgets(tx,81,stream);
  550.         }
  551.         bms = 0;
  552.         do
  553.         {
  554.             if (feof(stream)) break;
  555.             if (bms < 64)
  556.             {
  557.                 for(j=strlen(tx) ; (j > 0) && (isdigit(tx[j]) == 0) ; j--);
  558.                 for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  559.                 bdm[bms] = atoi(&tx[j]);
  560.                 for( ; (j > 0) && isspace(tx[j]) ; j--);
  561.                 tx[j+1] = 0;
  562.                 for( ; (j > 0) && (isspace(tx[j]) == 0) ; j--);
  563.                 bdf[bms] = atol(&tx[j]);
  564.                 if (fgets(bds[bms],73,stream) == NULL) break;
  565.                 bds[bms][strlen(bds[bms])-2] = 0;
  566.                 bms++;
  567.             }
  568.             fgets(tx,81,stream);
  569.         }
  570.         while (-1);
  571.         bm = bms;
  572.         fclose(stream);
  573.         if(((com >= 1)      && (com <= 4))
  574.         && ((bits >= 5)     || (bits <= 8))
  575.         && ((baud == 300)   || (baud == 600)
  576.         ||  (baud == 1200)  || (baud == 2400)
  577.         ||  (baud == 4800)  || (baud == 9600)
  578.         ||  (baud == 19200))
  579.         && ((stops == 1)    || (stops == 2))
  580.         && ((paron == 0)    || (paron == 1))
  581.         && ((parity == 0)   || (parity == 1))
  582.         && ((intrpt == 3)   || (intrpt == 4)))
  583.         {}
  584.         else
  585.         {
  586.             printf("COM data error in ICOM.INI\a");
  587.             return(1);
  588.         }
  589.         if(((fgd >= 0) && (fgd <= 15))
  590.         && ((bgd >= 0) && (bgd <= 7)))
  591.         {}
  592.         else
  593.         {
  594.             printf("Display data error in ICOM.INI\a");
  595.             return(1);
  596.         }
  597.     }
  598.     else
  599.     {
  600.         addr = 4;        /* ICOM IC735         */
  601.         com = 1;        /* COM1               */
  602.         bits = 8;        /* 8 data bits        */
  603.         baud = 1200;    /* 1200 baud          */
  604.         stops = 1;        /* stop bits = 1      */
  605.         paron = 0;        /* parity enable = Off*/
  606.         parity = 0;        /* parity = Even      */
  607.         intrpt = 4;        /* interrupt 4        */
  608.         fgd = 7;        /* foreground color   */
  609.         bgd = 0;        /* background color   */
  610.     }
  611.     if (addr == 4) fb = 8; else fb = 10;
  612.     for (i=0 ; prgm[i] != NULL ; i++)
  613.     {
  614.         prgm[i][aptr[i]] = hex[(addr >> 4) & 0xf];
  615.         prgm[i][aptr[i]+1] = hex[addr & 0xf];
  616.     }
  617.  
  618.     /*
  619.         Check COM port
  620.     */
  621.     if (peek(0x40,(com - 1) * 2) == 0)
  622.     {
  623.         printf("COM%d Not Available\a",com);
  624.         return(1);
  625.     }
  626.  
  627.     /*
  628.         Initialize COM port
  629.     */
  630.     oldcom = getvect(COM_VEC - (1 - (com & 1)));
  631.     setvect(COM_VEC - (1 - (com & 1)), newcom);
  632.  
  633.     /*
  634.         Reassign interrupt vectors
  635.     */
  636.     oldtmr = getvect(TMR_VEC);
  637.     setvect(TMR_VEC, newtmr);
  638.     return(0);
  639. }
  640.  
  641. /*********************/
  642. /*  Execute Program  */
  643. /*********************/
  644. prog(void)
  645. {
  646.  
  647.     /*
  648.         Initialize Display
  649.     */
  650.     gettextinfo(&dos_info);
  651.     if ((dos_info.currmode == BW40) || (dos_info.currmode == BW80))
  652.     {
  653.         dds = 0xb000;
  654.         textmode(BW80);
  655.         fgd = 7;
  656.         bgd = 0;
  657.     }
  658.     else
  659.     {
  660.         dds = 0xb800;
  661.         textmode(C80);
  662.     }
  663.  
  664.     /*
  665.         Save DOS Screen
  666.     */
  667.     for (i=0 ; i < 25 ; i++)
  668.         for (j=0 ; j < 160 ; j++)
  669.             dscr[i][j] = peekb(dds, i * 160 + j);
  670.  
  671.     /*
  672.         Setup Variables
  673.     */
  674.     get = put = first;
  675.     ptx = 0; cmd[10] = 0;
  676.  
  677.     /*
  678.         Setup Our Screen and COM Port
  679.     */
  680.     ref_scrn();
  681.  
  682.     do
  683.     {
  684.  
  685.         /*
  686.             Exit
  687.         */
  688.         if (slct)
  689.         if ((peekb(0x40, 0x17) & 0xf) == 0)
  690.         {
  691.             /*
  692.                 Restore DOS Screen
  693.             */
  694.             textmode(dos_info.currmode);
  695.             textattr(dos_info.attribute);
  696.             gotoxy(dos_info.curx,dos_info.cury);
  697.             for (i=0 ; i < 25 ; i++)
  698.                 for (j=0 ; j < 160 ; j++)
  699.                     pokeb(dds, i * 160 + j, dscr[i][j]);
  700.             return;
  701.         }
  702.  
  703.         /*
  704.             Check for I/O time out
  705.         */
  706.         if (rq && (ticks == 0))
  707.         {
  708.             ptx = rq = 0;
  709.             gotoxy(1,21);
  710.             cprintf("No response from radio...");
  711.         }
  712.  
  713.         /*
  714.             Do Up/Down
  715.         */
  716.         if (ud && (rq == 0) && (kbhit() == 0) && (tacks == 0))
  717.         {
  718.             f += (fi * ud);
  719.             if (bp >= 0)
  720.             {
  721.                 if (ud > 0)
  722.                 {
  723.                     if (f > fh[bp]) f = fl[bp];
  724.                 }
  725.                 else
  726.                 {
  727.                     if (f < fl[bp]) f = fh[bp];
  728.                 }
  729.             }
  730.             wr_freq();
  731.             tacks = td;
  732.         }
  733.  
  734.         /*
  735.             Do Memory to Vfo
  736.         */
  737.         if (tv && (rq == 0) && (kbhit() == 0))
  738.         {
  739.             rd_freq();
  740.             rqf = 1;
  741.             tv = 0;
  742.         }
  743.  
  744.         /*
  745.             New Band/Mode
  746.         */
  747.         if (bf && (rq == 0))
  748.         {
  749.             bf = 0;
  750.             wr_mode();
  751.         }
  752.  
  753.         /*
  754.             Check for input
  755.         */
  756.         if (kbhit() && (rq == 0))
  757.         {
  758.             ud = 0;
  759.             gotoxy(1,21); cprintf("%80.80s",""); gotoxy(1,1);
  760.             ch = toupper(getch());
  761.             switch (ch)
  762.             {
  763.             case 0:                /* Special Key */
  764.                 ch = getch();
  765.                 switch (ch)
  766.                 {
  767.                 case 15:        /* Back Tab */
  768.                     if (bms == 0) break;
  769.                     bm--;
  770.                     if (bm < 0) bm = bms - 1;
  771.                     f = bdf[bm]; m = bdm[bm];
  772.                     wr_freq(); bf = 1;
  773.                     gotoxy(1,21);
  774.                     cprintf(" %2d: %s",bm+1,bds[bm]);
  775.                     break;
  776.                 case 59:        /* F1 */
  777.                 case 60:        /* F2 */
  778.                 case 61:        /* F3 */
  779.                 case 62:        /* F4 */
  780.                 case 63:        /* F5 */
  781.                 case 64:        /* F6 */
  782.                     m = ch - 59;
  783.                     wr_mode();
  784.                     break;
  785.                 case 65:        /* F7 */
  786.                 case 66:        /* F8 */
  787.                     v = ch - 65;
  788.                     wr_vfo();
  789.                     break;
  790.                 case 67:        /* F9 */
  791.                     break;
  792.                 case 68:        /* F10 */
  793.                     break;
  794.                 case 72:        /* Up Arrow */
  795.                     f += 100;
  796.                     wr_freq();
  797.                     break;
  798.                 case 80:        /* Down Arrow */
  799.                     f -= 100;
  800.                     wr_freq();
  801.                     break;
  802.                 case 77:        /* Right Arrow */
  803.                     f += 500;
  804.                     wr_freq();
  805.                     break;
  806.                 case 75:        /* Left Arrow */
  807.                     f -= 500;
  808.                     wr_freq();
  809.                     break;
  810.                 case 73:        /* Page Up */
  811.                     f += 1000;
  812.                     wr_freq();
  813.                     break;
  814.                 case 81:        /* Page Down */
  815.                     f -= 1000;
  816.                     wr_freq();
  817.                     break;
  818.                 case 71:        /* Home */
  819.                     f += fi;
  820.                     wr_freq();
  821.                     break;
  822.                 case 79:        /* End */
  823.                     f -= fi;
  824.                     wr_freq();
  825.                     break;
  826.                 case 82:        /* Ins */
  827.                     gotoxy(1,21);
  828.                     if (bms == 64)
  829.                     {
  830.                         cprintf("**  No Room for Band/Mode  **");
  831.                         break;
  832.                     }
  833.                     for (bm=0 ; bm < bms ; bm++)
  834.                         if (bdf[bm] == f)
  835.                         {
  836.                             cprintf(" %2d: %s",bm+1,bds[bm]);
  837.                             gotoxy(1,1);
  838.                             break;
  839.                         }
  840.                     if (bm < bms) break;
  841.                     bdf[bms] = f; bdm[bms] = m;
  842.                     cprintf(" %2d? ",bms+1);
  843.                     gets(bds[bms]);
  844.                     if (bds[bms][0] == 0)
  845.                     {
  846.                         gotoxy(1,21);
  847.                         cprintf("**  Nothing Saved  **");
  848.                         break;
  849.                     }
  850.                     bds[bms++][72] = 0;
  851.                     gotoxy(1,1);
  852.                     break;
  853.                 case 83:        /* Del */
  854.                     if (bms == 0) break;;
  855.                     gotoxy(1,21);
  856.                     cprintf("Clear this Band/Mode? ");
  857.                     if (toupper(getch()) == 'Y')
  858.                     {
  859.                         for (bms-- ; bm < bms ; bm++)
  860.                         {
  861.                             bdf[bm] = bdf[bm+1];
  862.                             bdm[bm] = bdm[bm+1];
  863.                             strcpy(bds[bm],bds[bm+1]);
  864.                         }
  865.                         gotoxy(1,21);
  866.                         cprintf("**  Band/Mode is Clear  **");
  867.                     }
  868.                     else
  869.                     {
  870.                         gotoxy(1,21);
  871.                         cprintf("%80.80s","");
  872.                         gotoxy(1,1);
  873.                     }
  874.                     break;
  875.                 default:
  876.                     break;
  877.                 }
  878.                 break;
  879.             case 9:                /* Tab */
  880.                 if (bms == 0) break;
  881.                 bm++;
  882.                 if (bm >= bms) bm = 0;
  883.                 f = bdf[bm]; m = bdm[bm];
  884.                 wr_freq(); bf = 1;
  885.                 gotoxy(1,21);
  886.                 cprintf(" %2d: %s",bm+1,bds[bm]);
  887.                 break;
  888.             case 13:            /* Return */
  889.                 ref_scrn();
  890.                 break;
  891.             case 27:            /* ESCape */
  892.                 break;
  893.             case '.':
  894.                 ft = f - (f / 1000l) * 1000l;
  895.                 if (ft >= 500l) ft = 1000l; else ft = 0l;
  896.                 f = (f / 1000l) * 1000l + ft;
  897.                 wr_freq();
  898.                 break;
  899.             case 'B':
  900.                 if ((bp < 0) || (flh == 0)) break;
  901.                 f = fl[bp];
  902.                 wr_freq();
  903.                 break;
  904.             case 'C':
  905.                 gotoxy(1,19);
  906.                 cprintf("Enter Memory Channel (1-99): ");
  907.                 gets(tx);
  908.                 gotoxy(1,19); cprintf("%80.80s",""); gotoxy(1,1);
  909.                 c = atoi(tx);
  910.                 if ((c < 1) || (c > 99)) break;
  911.                 wr_ch();
  912.                 break;
  913.             case 'D':
  914.                 ud = -1;
  915.                 break;
  916.             case 'F':
  917.                 gotoxy(1,19);
  918.                 cprintf("Enter Frequency (KHz): ");
  919.                 gets(tx);
  920.                 gotoxy(1,19); cprintf("%80.80s",""); gotoxy(1,1);
  921.                 ft = cnv_txt(tx);
  922.                 if (ft == 0) break;
  923.                 if (tx[i] == '+')
  924.                     ft = f + ft;
  925.                 else
  926.                 if (tx[i] == '-')
  927.                     ft = f - ft;
  928.                 f = ft;
  929.                 wr_freq();
  930.                 break;
  931.             case 'I':
  932.                 gotoxy(1,19);
  933.                 cprintf("Scan Increment (KHz)");
  934.                 l = fi / 1000l;
  935.                 r = (fi - (l * 1000l)) / 10l;
  936.                 cprintf("[%ld.%02ld]: ",l,r);
  937.                 gets(tx);
  938.                 gotoxy(1,19); cprintf("%80.80s",""); gotoxy(1,1);
  939.                 ft = cnv_txt(tx);
  940.                 if ((ft == 0) || (tx[i] == '-')) break;
  941.                 fi = ft; td = fi / 55;    /* aprx 1KHz/sec */
  942.                 if (td > 18) td = 18;    /* 1 sec/inc max */
  943.                 break;
  944.             case 'L':
  945.                 rst_vect();
  946.                 gotoxy(1,21);
  947.                 if (ld_parm() == 0)
  948.                 {
  949.                     set_com();
  950.                     cprintf("**  List Loaded from Disk  **");
  951.                 }
  952.                 break;
  953.             case 'M':
  954.                 wr_tmem();
  955.                 gotoxy(1,21);
  956.                 cprintf("**  Wrote Vfo to Memory  **");
  957.                 break;
  958.             case 'N':
  959.                 if (flh == 0) break;
  960.                 tp = bp;
  961.                 for (bp=flh-1 ; (bp > 0) && (fl[bp] >= f) ; bp--);
  962.                 bp += 1;
  963.                 if (bp > (flh-1)) bp = 0;
  964.                 if (tp == bp) bp += 1;
  965.                 if (bp > (flh-1)) bp = 0;
  966.                 f = fl[bp]; bf = 1;
  967.                 wr_freq();
  968.                 break;
  969.             case 'P':
  970.                 if (flh == 0) break;
  971.                 tp = bp;
  972.                 for (bp=0 ; (bp < flh) && (fh[bp] <= f) ; bp++);
  973.                 bp -= 1;
  974.                 if (bp < 0) bp = flh-1;
  975.                 if (tp == bp) bp -= 1;
  976.                 if (bp < 0) bp = flh-1;
  977.                 f = fl[bp]; bf = 1;
  978.                 wr_freq();
  979.                 break;
  980.             case 'R':
  981.                 if ((bms == 0) || (bm == bms)) break;
  982.                 f = bdf[bm]; m = bdm[bm];
  983.                 wr_freq(); bf = 1;
  984.                 gotoxy(1,21);
  985.                 cprintf(" %2d: %s",bm+1,bds[bm]);
  986.                 break;
  987.             case 'S':
  988.                 gotoxy(1,21);
  989.                 stream = fopen(fn,"wb");
  990.                 if (stream == NULL)
  991.                 {
  992.                     cprintf("**  Cannot Open %s  **",fn);
  993.                     break;
  994.                 }
  995.                 fprintf(stream,ptxt[0],addr);
  996.                 for (i=0 ; i < flh ; i++)
  997.                 {
  998.                     fprintf(stream,"* %10ld %10ld\r\n",fl[i],fh[i]);
  999.                 }
  1000.                 for (i=1 ; parm[i] != NULL ; i++)
  1001.                 {
  1002.                     fprintf(stream,ptxt[i],*parm[i]);
  1003.                 }
  1004.                 if (bms)
  1005.                     for (i=0 ; i < bms ; i++)
  1006.                         fprintf(stream,"%10ld %2d\r\n%s\r\n",bdf[i],bdm[i],bds[i]);
  1007.                 fclose(stream);
  1008.                 cprintf("**  List Saved to Disk  **");
  1009.                 break;
  1010.             case 'T':
  1011.                 if (bp < 0) break;
  1012.                 f = fh[bp];
  1013.                 wr_freq();
  1014.                 break;
  1015.             case 'U':
  1016.                 ud = 1;
  1017.                 break;
  1018.             case 'V':
  1019.                 tv = 1;
  1020.                 wr_tvfo();
  1021.                 gotoxy(1,21);
  1022.                 cprintf("**  Wrote Memory to Vfo  **");
  1023.                 break;
  1024.             case 'Z':
  1025.                 if (bms == 0) break;
  1026.                 gotoxy(1,21);
  1027.                 cprintf("Clear List of Bands/Modes? ");
  1028.                 if (toupper(getch()) == 'Y')
  1029.                 {
  1030.                     bms = 0;
  1031.                     gotoxy(1,21);
  1032.                     cprintf("**  List of Bands/Modes are Clear  **");
  1033.                 }
  1034.                 else
  1035.                 {
  1036.                     gotoxy(1,21);
  1037.                     cprintf("%80.80s","");
  1038.                     gotoxy(1,1);
  1039.                 }
  1040.                 break;
  1041.             default:
  1042.                 break;
  1043.             }
  1044.         }
  1045.  
  1046.         /*
  1047.             Handle output
  1048.         */
  1049.         if (get != put)
  1050.         {
  1051.             ch = *get++;
  1052.             if (get == last) get = first;
  1053.             tx[ptx++] = ch;
  1054.             if (ch == 0xfd)        /* End Of Message Character */
  1055.             {
  1056.                 if (rq) rq--; if (rq == 0) ticks = 0;
  1057.                 dat[ptx*2] = 0;
  1058.                 for (i=ptx-1, j=0 ; i >= 0 ; i--)
  1059.                 {
  1060.                     dat[j++] = hex[(tx[i] >> 4) & 0xf];
  1061.                     dat[j++] = hex[tx[i] & 0xf];
  1062.                 }
  1063.  
  1064.                 if (j >= 12)
  1065.                 {
  1066.                     k = j - 10;
  1067.                     strncpy(cmd,&dat[k],10);
  1068.                     strncpy(dat,&dat[2],k-2);
  1069.                     dat[k-2] = 0;
  1070.  
  1071.                     if ((strcmp(cmd,prgm[0]) == 0) ||    /* Freq */
  1072.                         (strcmp(cmd,prgm[1]) == 0) ||    /* Mode */
  1073.                         (strcmp(cmd,prgm[2]) == 0) ||    /* Mem  */
  1074.                         (strcmp(cmd,prgm[3]) == 0) ||    /* Mem->VFO */
  1075.                         (strncmp(cmd,"0B",2) == 0) ||    /* Mem Clr */
  1076.                         (strncmp(cmd,"0C",2) == 0) ||    /* Ofst Rd */
  1077.                         (strncmp(cmd,"0D",2) == 0) ||    /* Ofst Wrt */
  1078.                         (strncmp(cmd,"0E",2) == 0))        /* Scan S/S */
  1079.                     {
  1080.                     }
  1081.                     else
  1082.                     if (strcmp(cmd,prgm[4]) == 0)        /* VFO  */
  1083.                     {
  1084.                         v = atoi(dat);
  1085.                         pvfo();
  1086.                     }
  1087.                     else
  1088.                     if (strcmp(cmd,prgm[5]) == 0)        /* Chan */
  1089.                     {
  1090.                         c = atoi(dat);
  1091.                         pchn();
  1092.                     }
  1093.                     else
  1094.                     if ((strcmp(cmd,prgm[6]) == 0) ||    /* Freq */
  1095.                         (strcmp(cmd,prgm[7]) == 0) ||
  1096.                         (strcmp(cmd,prgm[8]) == 0))
  1097.                     {
  1098.                         f = atol(dat);
  1099.                         pfreq();
  1100.                         if (rqf) rd_mode();
  1101.                     }
  1102.                     else
  1103.                     if ((strcmp(cmd,prgm[9]) == 0)  ||    /* Mode */
  1104.                         (strcmp(cmd,prgm[10]) == 0) ||
  1105.                         (strcmp(cmd,prgm[11]) == 0))
  1106.                     {
  1107.                         m = atoi(dat);
  1108.                         pmode();
  1109.                         if (rqf) rqf = 0;
  1110.                     }
  1111.                     else
  1112.                     {
  1113.                         gotoxy(1,21);
  1114.                         cprintf("Data Error: %s%s",dat,cmd);
  1115.                     }
  1116.                 }
  1117.             }
  1118.             if ((ch == 0xfd) || (ch == 0xfb)) ptx = 0;
  1119.         }
  1120.     }
  1121.     while (-1);
  1122. }
  1123.  
  1124. /******************/
  1125. /*  Main Program  */
  1126. /******************/
  1127. main(int argc, char *argv[])
  1128. {
  1129.  
  1130.     /*
  1131.         Get previous setup
  1132.  
  1133.         Edit the file ICOM.INI for your own COM and Screen
  1134.         preferences.  This program will create this file,
  1135.         if it doesn't exist, by use of the "Save List Disk"
  1136.         option.  If this file does not exist at run time,
  1137.         defaults for the IC735 are used.
  1138.     */
  1139.     fnsplit(argv[0],drv,dir,fn,fn);
  1140.     fnmerge(fn,drv,dir,"ICOM",".INI");
  1141.     if (ld_parm()) exit(1);
  1142.  
  1143.     if (argc == 2)
  1144.     {
  1145.         if (tolower(argv[argc-1][0]) == 'r')
  1146.         {
  1147.             printf("ICOM Programmer  Version %s  %s  %s\r\n\r\n",REV,__DATE__,__TIME__);
  1148.             sss = _SS;
  1149.     /*
  1150.                 **  NOTE  **
  1151.  
  1152.         The value 2560 in the next statement is the number of bytes of
  1153.         stack space required by our program, space required for some
  1154.         arrays AND 1K of space for each file we open (i.e. 1 in the
  1155.         original program).  Be sure to allow sufficient space if you
  1156.         add additional file I/O.
  1157.     */
  1158.             ssp = 2560 + ((unsigned int) _atexittbl / 16 + 1) * 16;
  1159.             active = 0;
  1160.             keep(0, ssp / 16 + 1);
  1161.         }
  1162.     }
  1163.     else
  1164.     {
  1165.         prog();
  1166.         rst_vect();
  1167.     }
  1168.  
  1169.     return;
  1170. }
  1171.