home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / modem / comm.arc / COMM.C
Text File  |  1985-06-03  |  5KB  |  309 lines

  1.  
  2. COMM.C.1
  3.  
  4.  
  5.  
  6. /* NOTE: this code is indented using tabs set every 4 columns, not 8. */
  7.  
  8. /*
  9.  * Rudimentary communication program; written in C with I/O
  10.  * routines in assembler, using "#asm" construct in DeSmet C.
  11.  */
  12.  
  13. #define TRUE 1
  14. #define FALSE 0
  15. #define NULL 0
  16.  
  17. #define comm_stat head!=tail
  18.  
  19. int head=0,
  20.     tail=0;
  21.  
  22. char comm_buffer[8192];
  23.  
  24. main()
  25.     char commget();
  26.  
  27.     int c,
  28.         echo=FALSE,
  29.         verbose=FALSE;
  30.  
  31.     initcomm();
  32.  
  33.     goto inside;
  34.     while((c=my_ci())<256) /* alt's and function keys are >=256 */
  35.     {
  36.         commput(c);
  37.         if(echo)
  38.             my_co(c);
  39. inside:    while(my_stat()==0)
  40.             if(comm_stat)
  41.                 if(is_nice(c=commget()))
  42.                     my_co(c);
  43.                 else
  44.                     if(verbose)
  45.                     {
  46.                         my_co('^');
  47.                         my_co(127&(c+'@'));
  48.                     } 
  49.     }
  50.     switch(c>>8) /* process function key */
  51.     {
  52.         case '\060': /* b    send break    */
  53.             make_break();
  54.             my_puts("** break **\n");
  55.             break;
  56.         case '\022': /* e    echo toggle    */
  57.             echo = !echo;
  58.             if(echo)
  59.                 my_puts("** echo on **\n");
  60.             else
  61.                 my_puts("** echo off **\n");
  62.             break;
  63.         case '\020': /* q    quit        */
  64.             my_puts("** returning to DOS **\n");
  65.             goto byebye;
  66.         case '\057': /* v    verbose        */
  67.             verbose = !verbose;
  68.             if(verbose)
  69.                 my_puts("** verbose on **\n");
  70.             else
  71.                 my_puts("** verbose off **\n");
  72.             break; 
  73.     }
  74.     goto inside;
  75.  
  76. byebye:
  77.     killcomm();
  78. }
  79.  
  80. initcomm()
  81. {
  82. #asm
  83.  
  84. ; initialize communication port,
  85. ; and install interrupt handler
  86.  
  87. ; save dseg for interrupt handler
  88.     mov        ax,ds
  89.     mov        cs:dssave,ax
  90.  
  91. ; set int vector to my handler
  92.     push    ds
  93.     xor        ax,ax
  94.     mov        ds,ax
  95.     mov        [30h],offset handler
  96.     mov        ax,cs 
  97.     mov        [32h],ax
  98.     pop        ds
  99.  
  100. ; assert DTR, RTS, and OUT2
  101.     mov        dx,3fch
  102.     mov        al,11
  103.     out        dx,al
  104.  
  105. ; enable interrupts for data ready
  106.     mov        dx,3f9h
  107.     mov        al,1
  108.     out        dx,al
  109.  
  110. ; clear any outstanding int
  111.     mov        dx,3f8h
  112.     in        al,dx
  113.  
  114. ; enable interrupts
  115.     sti
  116.  
  117. ; enable IRQ4 on 8259A
  118.     in        al,21h
  119.     and        al,0efh
  120.     out        21h,al 
  121.  
  122. ; and return
  123.     jmp        init_finis
  124.  
  125. dssave:    dw 0
  126.  
  127. handler:
  128.     push    ds
  129.     push    ax
  130.     push    dx
  131.     push    bx
  132.  
  133. ; restore appropriate dseg
  134.     mov        ax,cs:dssave
  135.     mov        ds,ax
  136.  
  137. ; grab the byte from comm port
  138.     mov        dx,3f8h
  139.     in        al,dx
  140.  
  141. ; put it in the buffer
  142.     mov        bx,tail_
  143.     mov        comm_buffer_[bx],al
  144.  
  145. ; tail=tail+1 (mod 8192)
  146.     inc        bx
  147.     cmp        bx,8192
  148.     jl        handler_around
  149.     xor        bx,bx
  150.  
  151. handler_around:
  152.     mov        tail_,bx
  153.  
  154. ; tell the 8259A EOI
  155.     mov        dx,20h
  156.     mov        al,32
  157.     out        dx,al
  158.  
  159.     pop        bx
  160.     pop        dx
  161.     pop        ax
  162.     pop        ds
  163.  
  164. ; reenable interrupts
  165.     sti
  166.  
  167.     iret
  168.  
  169. init_finis:
  170. #
  171. }
  172.  
  173. commput(c)
  174. int c;
  175. {
  176. #asm
  177. ; put the character out the port
  178.     mov        dx,3f8h
  179.     mov        ax,[bp+4]
  180.     out        dx,al
  181. #
  182. }
  183.  
  184. char commget()
  185. {
  186.     char temp;
  187.  
  188.         temp=comm_buffer[head++];
  189.         head%=8192;
  190.         return(temp);
  191. }
  192.  
  193. killcomm()
  194. {
  195. #asm
  196. ; disconnect the interrupt handler
  197.     in        al,21h
  198.     or        al,10h
  199.     out        21h,al
  200. #
  201. }
  202.  
  203. make_break()
  204. {
  205. #asm
  206. ; set bit on LCR
  207.     mov        dx,3fbh
  208.     in        al,dx
  209.     push    ax
  210.     or        al,40h
  211.     out        dx,al
  212.  
  213. ; wait a wee bit (~200 ms)
  214.     mov        bx,8
  215. outer:
  216.     mov        cx,7000 
  217. tight:
  218.     loop    tight
  219.     dec        bx
  220.     jnz        outer
  221.  
  222. ; and turn break back off
  223.     pop        ax
  224.     out        dx,al
  225. #
  226. }
  227.  
  228. is_nice(c) /* true for those characters that "should" be received */
  229. char c;
  230. {
  231.     c&=127;
  232.     if(c>=' ' && c<='~')    /* printable */
  233.         return(TRUE);
  234.     if(c>6 && c<11)            /* BEL, BS, HT, LF */
  235.         return(TRUE);
  236.     if(c==13 || c==27)        /* CR, ESC */
  237.         return(TRUE);
  238.     return(FALSE);
  239. }
  240.  
  241. my_puts(s) /* puts, using my_co() */
  242. char *s;
  243. {
  244.     while(*s)
  245.     {
  246.         if(*s=='\n')
  247.             my_co('\r');
  248.         my_co(*(s++));
  249.     }
  250. }
  251.  
  252. my_co(c) /* character output, smaller and faster than DeSmet's,
  253.             using DOS function call 2.00 */
  254. char c;
  255. {
  256. #asm
  257.     mov        ah,2
  258.     mov        dx,[bp+4]
  259.     int        21h
  260. #
  261. }
  262.  
  263. my_stat() /* true if character is ready from keyboard */
  264. #asm
  265.     mov        ah,1
  266.     int        16h
  267.     jz        stat_no_char
  268.     mov        ax,1
  269.     jmp        stat_finis
  270.  
  271. stat_no_char:
  272.     xor        ax,ax
  273.  
  274. stat_finis:
  275. #
  276. }
  277.  
  278. my_ci() /* get character from keyboard, using BIOS function call */
  279. {
  280. #asm
  281.     xor        ah,ah
  282.     int        16h
  283.     or        al,al
  284.     jz        my_ci_finis
  285.     xor        ah,ah
  286.  
  287. my_ci_finis: 
  288. #
  289. }
  290. ------------------------------------------------------------------------------
  291. The termcap for DOS 2.00 with ansi device driver follows:
  292. ------------------------------------------------------------------------------
  293. pm|pcmon|IBM-PC using DOS 2.00 ansi device driver (monochrome)|\
  294.     :am:bc=^H:bw:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:\
  295.     :do=^J:ho=\E[H:kb=^H:li#25:ll=\E[25H:nd=\E[C:\
  296.     :pt:se=\E[0m:so=\E[1m:ta=^I:up=\E[A:xt:
  297. pc|pccol|IBM-PC using DOS 2.00 ansi device driver (color)|\
  298.     :am:bc=^H:bw:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:\
  299.     :do=^J:ho=\E[H:kb=^H:li#25:ll=\E[25H:nd=\E[C:\
  300.     :pt:se=\E[0;32m:so=\E[1m:ta=^I:up=\E[A:xt:
  301. ------------------------------------------------------------------------------
  302. and that's it! Enjoy. I place this in the public domain, and would appreciate
  303. feedback. Improvements and bug reports especially desired. If the code is too
  304. cryptic or uncommented, feel free to send questions to:
  305.                     Bennett Todd
  306.                     ...{decvax,ihnp4,akgua}!mcnc!ecsvax!bet
  307.