summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/mterm.c
blob: b0225041aa26a5c8ab552023cdb09f0ea620fe23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* MTERM.C - Minimal example PC terminal program.
   Released to public domain by author, David Harmon, June 1992.
   Intended for use with a FOSSIL driver, but will run with BIOS alone.
   I expect you'll want to add something for practical purposes. ;-)
*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>            /* kbhit(), getch(), putch(), etc. */
#include <dos.h>              /* int86(), etc. */

#ifdef __ZTC__
 #define cputs(s) fputs((s),stderr)
#endif

int port = 0;                 /* 0 = COM1:, 1 = COM2: etc. */
int local_echo = 0;
int cr_add_lf = 0;
int exiting = 0;

int init_comm(int flags)
{
      union REGS regs;

      regs.h.ah = 0x04;         /* initialize driver (port) */
      regs.x.bx = 0x4f50;
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);

      regs.h.ah = 0x00;         /* set baud rate * port attrs */
      regs.h.al = (unsigned char)flags;
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);
      return regs.h.ah;
}

void send_char(char ch)
{
      union REGS regs;

      regs.h.ah = 0x01;         /* Send char (wait until ready)*/
      regs.h.al = ch;
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);
}

int   input_ready(void)
{
      union REGS regs;

      regs.h.ah = 0x03;         /* Get port status */
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);
      return ((regs.h.ah & 0x01) != 0);   /* input ready */
}

int   get_char(void)
{
      union REGS regs;

      regs.h.ah = 0x02;         /* receive char (wait if necessary)*/
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);
      return regs.h.al;
}

void deinit_comm(void)
{
      union REGS regs;

      regs.h.ah = 0x05;         /* deinitialize port (pseudo close) */
      regs.h.al = 0x00;         /* (lower DTR) */
      regs.x.dx = port;
      int86( 0x14, &regs, &regs);
}

void main(void)
{
      int ch;

      init_comm(0xE3);          /* hard coded 0xB3 = 2400,N,8,1 */
      cputs("MTERM ready!   Press F1 to exit.\r\n");
      while (!exiting)
      {
            if (kbhit())        /* key was hit */
            {
                  ch = getch();     /* Regular ASCII keys are returned as the
                                       ASCII code; function keys, arrows, etc.
                                       as zero followed by a special code
                                       (on next getch.)  */
                  if (ch != 0)
                  {
                        send_char((char)ch);    /* to com port */
                        if (local_echo)
                        {
                              putch(ch);        /* to screen */

                              /* add LF to CR? */

                              if (cr_add_lf && ch == '\r')
                                    putch('\n');
                        }
                  }
                  else
                  {
                        ch = getch();       /* get the special key code */
                        switch (ch)
                        {
                        case 0x3B: /* F1 */
                              exiting = 1;               /* quit now */
                              break;

                        case 0x3C: /* F2 */
                              local_echo = !local_echo;  /* toggle echo */
                              break;

                        case 0x3D: /* F3 */
                              cr_add_lf = !cr_add_lf;    /* toggle LF */
                              break;
                        }
                  }
            } /* end if kbhit */

            if (input_ready())       /* com port */
            {
                  ch = get_char();
                  putch(ch);
                  if (cr_add_lf && ch == '\r')  /* add LF to CR? */
                        putch('\n');
            }
      } /* end while not exiting */
      deinit_comm();
}