home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / pcserial.zoo / serial.2 < prev    next >
Encoding:
Text File  |  1990-04-04  |  45.2 KB  |  1,924 lines

  1.  
  2. #! /bin/sh
  3. # This is a shell archive.  Remove anything before this line, then unpack
  4. # it by saving it into a file and typing "sh file".  To overwrite existing
  5. # files, type "sh file -c".  You can also feed this as standard input via
  6. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  7. # will see the following message at the end:
  8. #        "End of archive 2 (of 3)."
  9. # Contents:  8250dtr.c 8250xon.c _kb.c options.c screen.c
  10. # Wrapped by jb@deneb on Sat Mar 24 10:42:18 1990
  11. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  12. if test -f '8250dtr.c' -a "${1}" != "-c" ; then 
  13.   echo shar: Will not clobber existing file \"'8250dtr.c'\"
  14. else
  15. echo shar: Extracting \"'8250dtr.c'\" \(11252 characters\)
  16. sed "s/^X//" >'8250dtr.c' <<'END_OF_FILE'
  17. X/*
  18. X *                                DTR8250.C
  19. X *
  20. X *                    NSC8250 DTR Handshake ISR Module
  21. X *
  22. X *                           Written for the
  23. X *
  24. X *                              Datalight
  25. X *                           Microsoft V 5.x
  26. X *                                TurboC
  27. X *                                  &
  28. X *                               Zortech
  29. X *
  30. X *                             C Compilers
  31. X *
  32. X *            Copyright (c) John Birchfield 1987, 1988, 1989
  33. X */
  34. X
  35. X#include <stdio.h>
  36. X#include "dependnt.h"
  37. X#include "queue.h"
  38. X#include "8250nsc.h"
  39. X#include "8250dtr.h"
  40. X#include "timer.h"
  41. X
  42. X#if (!defined (TRUE))
  43. X#    define TRUE  (1)
  44. X#    define FALSE (0)
  45. X#endif
  46. X
  47. unsigned DTR_PORT_channel;      /* Either 1 or 2 for COM1 or COM2       */
  48. char    dtr8250_SAVE_int_mask,  /* saved interrupt controller mask word */
  49. X        dtr8250_IER_save = 0,   /* Saved off Interrupt Enable Register  */
  50. X        dtr8250_LCR_save = 0,   /* Saved off Line Control Register      */
  51. X        dtr8250_MCR_save = 0,   /* Saved off Modem Control Register     */
  52. X        dtr8250_DL_lsb = 0,     /* Saved off Baud Rate LSB              */
  53. X        dtr8250_DL_msb = 0;     /* Saved off Baud Rate MSB              */
  54. X
  55. X
  56. X
  57. volatile unsigned DTR_PORT_addr;
  58. volatile char DTR_PORT_status, RCV_disabled = FALSE, XMIT_disabled = TRUE, dtr8250_MSR_reg = 0;
  59. volatile QUEUE *dtr8250_inqueue;
  60. X#if (defined (DLC))
  61. extern void outp ();
  62. X#endif
  63. X
  64. X
  65. X#define DISABLE_xmit outbyte (DTR_PORT_addr+IER, RX_enable)
  66. X#define ENABLE_xmit  outbyte (DTR_PORT_addr+IER, RX_TX_enable)
  67. X#define DROPPED_cts  ((dtr8250_MSR_reg&0x10)==0)
  68. X#define DROPPED_dsr  ((dtr8250_MSR_reg&0x20)==0)
  69. X#define DROPPED_dtr  ((dtr8250_MSR_reg&0x30)!=0x30)
  70. X#define ASSERT_dtr   outbyte (inbyte (DTR_PORT_addr+MCR)|9, DTR_PORT_addr+MCR)
  71. X#define DROP_dtr     outbyte (inbyte (DTR_PORT_addr+MCR)&0x0A, DTR_PORT_addr+MCR)
  72. X#define ASSERT_rts   outbyte (inbyte (DTR_PORT_addr+MCR)|0x0A, DTR_PORT_addr+MCR)
  73. X#define DROP_rts     outbyte (inbyte (DTR_PORT_addr+MCR)&9, DTR_PORT_addr+MCR)
  74. X#define TSRE_bit     0x40
  75. X
  76. X
  77. X
  78. X/*
  79. X *    DTR8250_ISR - This Interrupt Service Routine attached to either COM1
  80. X *                  or COM2.  It drives the NSC8250 with Hardware
  81. X *                  Handshaking.  i.e. Flow of Control is maintained by 
  82. X *                  RTS (Request to Send) CTS (Clear to Send) Logic.
  83. X *                After installation by Catch_Rt, it catches the
  84. X *                8250 interrupts and en_queues incoming characters
  85. X *                from the Serial Port - and de-queues outgoing
  86. X *                characters to the Serial Port.
  87. X */
  88. X
  89. X#if (!defined (DLC))
  90. void    (interrupt far * dtr_save_vec) (void);
  91. void interrupt far 
  92. dtr8250_isr (void)
  93. X#else
  94. int 
  95. dtr8250_isr ()
  96. X#endif
  97. X{
  98. X    int     ch;
  99. X    char    test_status;
  100. X
  101. X    enable ();
  102. X    test_status = inbyte ((DTR_PORT_addr + IIR));
  103. X    do
  104. X    {
  105. X        switch (test_status)
  106. X        {
  107. X
  108. X            case IIR_rls:
  109. X                DTR_PORT_status |= inbyte ((DTR_PORT_addr + LSR));
  110. X                break;
  111. X
  112. X            case IIR_receive:
  113. X                ch = inbyte (DTR_PORT_addr);
  114. X                if ((en_queue (dtr8250_inqueue, ch) < 10) && !RCV_disabled)
  115. X                {
  116. X                    RCV_disabled = TRUE;
  117. X                    DROP_dtr;
  118. X                }
  119. X                else
  120. X                if (RCV_disabled && (queue_avail (dtr8250_inqueue) > 20))
  121. X                {
  122. X                    RCV_disabled = FALSE;
  123. X                    ASSERT_dtr;
  124. X                }
  125. X                break;
  126. X
  127. X            case IIR_transmit:
  128. X                DISABLE_xmit;
  129. X                break;
  130. X
  131. X            case IIR_mstatus:
  132. X                dtr8250_MSR_reg = inbyte (DTR_PORT_addr + MSR);
  133. X                if (RCV_disabled && (queue_avail (dtr8250_inqueue) > 20))
  134. X                {
  135. X                    RCV_disabled = FALSE;
  136. X                    ASSERT_dtr;
  137. X                }
  138. X                break;
  139. X        }
  140. X    } while ((test_status = inbyte (DTR_PORT_addr + IIR)) != IIR_complete);
  141. X    disable ();
  142. X    outbyte (INT_cntrl, EOI_word);
  143. X#if (defined (DLC))
  144. X    return (1);
  145. X#endif
  146. X}
  147. X
  148. X
  149. X
  150. X
  151. X/*
  152. X *    DTR8250_INIT - Here we get the address of the 8250 Port
  153. X *                   which corresponds to the channel passed in.
  154. X *                   We then massage the 8259 Interrupt Controller
  155. X *                   calculate the Physical Interrupt and save off
  156. X *                   the 8250's current contents.  Then attach the
  157. X *                   nsc8250_interrupt routine to the interrupt and
  158. X *                   return the rt returned index for saving - it's
  159. X *                   needed to terminate the interrupt.
  160. X */
  161. X
  162. X#define DTR8250_STACK_SIZE 1024
  163. int        dtr8250_intno;
  164. static int dtr_intmask [] = { 0xef, 0xf7, 0xef, 0xf7 };
  165. X/*
  166. X * The above 8259 mask bits are determined from the formula
  167. X *          mask = ~(1 << (5 - PORT_CHANNEL));
  168. X * The array assumes that COM3 and COM4 use the same interrupts
  169. X * as COM1 and COM2.
  170. X */
  171. static int dtr_intno   [] = { 12, 11, 12, 11 };
  172. X/*
  173. X * The above interrupt number array is based on the algorithm
  174. X *       dtr8250_intno = (13 - PORT_channel);
  175. X */
  176. X
  177. X
  178. void 
  179. dtr8250_init (channel, buf_size)
  180. int     channel, buf_size;
  181. X{
  182. X    int     Dos_address, mask;
  183. X    DTR_PORT_channel = channel;
  184. X    dtr8250_inqueue = alloc_queue (buf_size);
  185. X    Dos_address = (DTR_PORT_channel - 1) * 2;
  186. X    peekmem (0x40, Dos_address, DTR_PORT_addr);
  187. X    mask = dtr_intmask [DTR_PORT_channel-1];
  188. X    dtr8250_SAVE_int_mask = inbyte (INT_mask);
  189. X    mask &= dtr8250_SAVE_int_mask;
  190. X    dtr8250_intno = dtr_intno [DTR_PORT_channel-1];
  191. X    dtr8250_LCR_save = inbyte (DTR_PORT_addr + LCR);
  192. X    disable ();
  193. X    outbyte (DTR_PORT_addr + LCR, dtr8250_LCR_save | LCR_DLAB);
  194. X    dtr8250_MCR_save = inbyte (DTR_PORT_addr + MCR);
  195. X    dtr8250_DL_lsb = inbyte (DTR_PORT_addr);
  196. X    dtr8250_DL_msb = inbyte (DTR_PORT_addr + 1);
  197. X    outbyte (DTR_PORT_addr + LCR, dtr8250_LCR_save & 0x7F);
  198. X    dtr8250_IER_save = inbyte (DTR_PORT_addr + IER);
  199. X    enable ();
  200. X#if (defined (DLC))
  201. X    int_intercept (dtr8250_intno, &dtr8250_isr, DTR8250_STACK_SIZE);
  202. X#else
  203. X    dtr_save_vec = getvect (dtr8250_intno);
  204. X    setvect (dtr8250_intno, dtr8250_isr);
  205. X#endif
  206. X    DELAY_init ();
  207. X    outbyte (INT_mask, mask);
  208. X}
  209. X
  210. X
  211. X
  212. X
  213. X/*
  214. X *    DTR8250_TERM - This routine restores the RS232 Vector back to its
  215. X *                   state before DTR8250_INIT was called.
  216. X */
  217. X
  218. void 
  219. dtr8250_term (int restore)
  220. X{
  221. X    disable ();
  222. X    outbyte (INT_mask, dtr8250_SAVE_int_mask);
  223. X    if (restore)
  224. X    {
  225. X        outbyte (DTR_PORT_addr + LCR, LCR_DLAB);
  226. X        outbyte (DTR_PORT_addr, dtr8250_DL_lsb);
  227. X        outbyte (DTR_PORT_addr + 1, dtr8250_DL_msb);
  228. X        outbyte (DTR_PORT_addr + MCR, dtr8250_MCR_save);
  229. X        outbyte (DTR_PORT_addr + LCR, 0x7F);
  230. X        outbyte (DTR_PORT_addr + IER, dtr8250_IER_save);
  231. X        outbyte (DTR_PORT_addr + LCR, dtr8250_LCR_save);
  232. X    }
  233. X#if (defined (DLC))
  234. X    int_restore (dtr8250_intno);
  235. X#else
  236. X    setvect (dtr8250_intno, dtr_save_vec);
  237. X#endif
  238. X}
  239. X
  240. X
  241. X
  242. X
  243. X/*
  244. X *    DTR8250_READ - this routine looks in the RS232hw_inqueue for a character
  245. X *
  246. X */
  247. X
  248. int 
  249. dtr8250_read (void)
  250. X{
  251. X    int     ch;
  252. X    disable ();
  253. X    ch = de_queue (dtr8250_inqueue);
  254. X    enable ();
  255. X    return (ch);
  256. X}
  257. X
  258. X
  259. X
  260. X
  261. X/*
  262. X *    DTR8250_TIMED_READ - attempts to read rs232 port - if no char
  263. X *                         available in number of seconds passed
  264. X *                         returns -1
  265. X */
  266. X
  267. int 
  268. dtr8250_timed_read (int sec)
  269. X{
  270. X    int     ch;
  271. X
  272. X    timer_set ();
  273. X    while ((ch = dtr8250_read ()) == -1)
  274. X        if ((timer_read () / 18) > sec)
  275. X            break;
  276. X    return (ch);
  277. X}
  278. X
  279. X
  280. X
  281. X
  282. X/*
  283. X *    DTR8250_WRITE - plain vanilla write to the port - check to see that
  284. X *                    the chip may need a kick in the pants before returning
  285. X */
  286. X
  287. int 
  288. dtr8250_write (char ch)
  289. X{
  290. X    while ((inbyte (DTR_PORT_addr + LSR) & TSRE_bit) == 0)
  291. X        ;
  292. X    dtr8250_MSR_reg = inbyte ((DTR_PORT_addr + MSR));
  293. X    if (DROPPED_dtr)
  294. X        return -1;
  295. X    outbyte (DTR_PORT_addr, ch);
  296. X    if (RCV_disabled && (queue_avail (dtr8250_inqueue) > 20))
  297. X    {
  298. X        RCV_disabled = FALSE;
  299. X        ASSERT_dtr;
  300. X    }
  301. X}
  302. X
  303. X
  304. X
  305. X
  306. X/*
  307. X *    DTR8250_DTRNR - drop Data Terminal Ready Line
  308. X */
  309. void
  310. dtr8250_dtnr (void)
  311. X{
  312. X    char mcr_save;
  313. X    disable ();
  314. X    mcr_save = inbyte (DTR_PORT_addr + MCR);
  315. X    outbyte (DTR_PORT_addr + MCR, 0);
  316. X    DELAY_loop (500);
  317. X    outbyte (DTR_PORT_addr + MCR, mcr_save);
  318. X    enable ();
  319. X}
  320. X
  321. X
  322. X
  323. X
  324. X/*
  325. X *    DTR8250_GET_STATUS - returns the current NSC8250 status and
  326. X *                         resets any error condition.
  327. X */
  328. X
  329. int 
  330. dtr8250_get_status (void)
  331. X{
  332. X    char    rval = DTR_PORT_status;
  333. X    DTR_PORT_status &= ERROR_reset;
  334. X    return ((int) rval);
  335. X}
  336. X
  337. X
  338. X
  339. X
  340. X
  341. X/*
  342. X *    DTR8250_MODEM_STATUS - returns the current NSC8250 Modm Status Register
  343. X *                           contents.
  344. X */
  345. X
  346. int 
  347. dtr8250_modem_status (void)
  348. X{
  349. X    dtr8250_MSR_reg = inbyte (DTR_PORT_addr + MSR);
  350. X    return ((int) dtr8250_MSR_reg);
  351. X}
  352. X
  353. X
  354. X
  355. X
  356. X
  357. X/*
  358. X *    DTR8250_WRITE_BREAK - Write a BREAK Character
  359. X */
  360. X
  361. void 
  362. dtr8250_write_break (void)
  363. X{
  364. X    int     i;
  365. X    disable ();
  366. X    while ((inbyte (DTR_PORT_addr + LSR) & 0x40) == 0)
  367. X        ;
  368. X    outbyte (DTR_PORT_addr + LCR, inbyte (DTR_PORT_addr + LCR) | 0x40);
  369. X    for (i = 0; i < 13000; i++)
  370. X        ;
  371. X    outbyte (DTR_PORT_addr + LCR, inbyte (DTR_PORT_addr + LCR) & 0xBF);
  372. X    enable ();
  373. X}
  374. X
  375. X
  376. X
  377. X
  378. X
  379. X/*
  380. X *    DTR8250_PORT_INIT (Cmd) configures the 8250
  381. X *        cmd is a string of the form baud parity stop data i.e 
  382. X *        300 n 1 8
  383. X *
  384. X *        baud - 300, 600, 1200, 2400, 4800, 9600
  385. X *        parity - n -> no parity check
  386. X *                 o -> odd parity
  387. X *                 e -> even parity
  388. X *        stop   - 1 -> 1 stop bit
  389. X *                 2 -> 2 stop bits
  390. X *        data   - 5, 6, 7, 8 data bits
  391. X */
  392. X
  393. void 
  394. dtr8250_port_init (cmd)
  395. char   *cmd;
  396. X{
  397. X    unsigned baud, data, mode_word, parity, stop, xoff;
  398. X    char    pty[2];
  399. X    sscanf (cmd, "%d %1s %d %d", &baud, pty, &stop, &data);
  400. X    *pty = toupper (*pty);
  401. X    switch (*pty)
  402. X    {
  403. X        case 'E':
  404. X            parity = 3;
  405. X            break;
  406. X        case 'O':
  407. X            parity = 1;
  408. X            break;
  409. X        case 'N':
  410. X            parity = 0;
  411. X            break;
  412. X        default:
  413. X            parity = 0;
  414. X            break;
  415. X    }
  416. X    stop = (--stop & 1);
  417. X    stop <<= 2;
  418. X    baud /= 10;
  419. X    baud = 11520 / baud;
  420. X    parity <<= 3;
  421. X    parity &= 0x018;
  422. X    data -= 5;
  423. X    data &= 3;
  424. X    mode_word = data | stop | parity;
  425. X    disable ();
  426. X    outbyte (DTR_PORT_addr + LCR, inbyte (DTR_PORT_addr + LCR) | LCR_DLAB);
  427. X    outbyte (DTR_PORT_addr, baud % 256);
  428. X    outbyte (DTR_PORT_addr + 1, baud / 256);
  429. X    outbyte (DTR_PORT_addr + LCR, mode_word & 0x7F);
  430. X    outbyte (DTR_PORT_addr + IER, RX_enable);
  431. X    outbyte (DTR_PORT_addr + MCR, 0x0B);
  432. X
  433. X    inbyte (DTR_PORT_addr + LSR);
  434. X    dtr8250_MSR_reg = inbyte ((DTR_PORT_addr + MSR));
  435. X    inbyte (DTR_PORT_addr);
  436. X    enable ();
  437. X}
  438. X
  439. X
  440. X
  441. X
  442. X/*---------------------- dtr8250_port_enable () ----------------------*/
  443. X/*
  444. X *
  445. X */
  446. void
  447. dtr8250_port_enable (void)
  448. X{
  449. X    disable ();
  450. X    outbyte (DTR_PORT_addr + IER, RX_enable);
  451. X    outbyte (DTR_PORT_addr + MCR, 0x0B);
  452. X
  453. X    inbyte (DTR_PORT_addr + LSR);
  454. X    dtr8250_MSR_reg = inbyte ((DTR_PORT_addr + MSR));
  455. X    inbyte (DTR_PORT_addr);
  456. X    enable ();
  457. X}
  458. X
  459. X
  460. X
  461. X
  462. X/*------------------------ dtr8250_lines () ------------------------*/
  463. X/*
  464. X *
  465. X */
  466. void
  467. dtr8250_lines (void)
  468. X{
  469. X    printf ("8250 DTR_PORT_addr = %04x\n", DTR_PORT_addr);
  470. X    printf ("8250 MSR = %02x\n", inbyte (DTR_PORT_addr + MSR));
  471. X}
  472. END_OF_FILE
  473. if test 11252 -ne `wc -c <'8250dtr.c'`; then
  474.     echo shar: \"'8250dtr.c'\" unpacked with wrong size!
  475. fi
  476. # end of '8250dtr.c'
  477. fi
  478. if test -f '8250xon.c' -a "${1}" != "-c" ; then 
  479.   echo shar: Will not clobber existing file \"'8250xon.c'\"
  480. else
  481. echo shar: Extracting \"'8250xon.c'\" \(12190 characters\)
  482. sed "s/^X//" >'8250xon.c' <<'END_OF_FILE'
  483. X/*
  484. X *                               8250XON.C
  485. X *
  486. X *                   NSC8250 RS232 Xon/Xoff ISR Routine
  487. X *
  488. X *                           Written for the
  489. X *
  490. X *                              Datalight
  491. X *                           Microsoft V 5.x
  492. X *                                TurboC
  493. X *                                  &
  494. X *                               Zortech
  495. X *
  496. X *                             C Compilers
  497. X *
  498. X *            Copyright (c) John Birchfield 1987, 1988, 1989
  499. X */
  500. X
  501. X
  502. X#include <stdio.h>
  503. X#include "dependnt.h"
  504. X#include "delay.h"
  505. X#include "8250nsc.h"
  506. X#include "8250xon.h"
  507. X#include "queue.h"
  508. X#include "timer.h"
  509. X
  510. X#if (!defined (TRUE))
  511. X#    define TRUE (1)
  512. X#    define FALSE (0)
  513. X#endif
  514. X
  515. X
  516. X#define I_BUF_SIZE 4096 /* inbyteut  Buffer Size  */
  517. X#define O_BUF_SIZE 4096 /* output Buffer Size */
  518. X
  519. volatile unsigned XON_PORT_address = 0x03F8;
  520. volatile char     xoff_enabled     = FALSE,
  521. X                  xoff_sent        = FALSE, 
  522. X                  xoff_received    = FALSE,
  523. X                  XON_PORT_status  = 0,
  524. X                  XON_PORT_state   = 0,
  525. X                  XON_PORT_command = 0,
  526. X                  XON_char         = 0x11,
  527. X                  XOFF_char        = 0x13;
  528. X
  529. char          XON_PORT_channel = 1,
  530. X              SAVE_int_mask = 0,      /* saved interrupt controller mask word */
  531. X
  532. X/*
  533. X *    8250 register save locations and base address offsets
  534. X */
  535. X        IER_save = 0, LCR_save = 0, MCR_save = 0, DL_lsb = 0, DL_msb = 0;
  536. X
  537. X
  538. X
  539. X
  540. QUEUE  *xon8250_inqueue, *xon8250_outqueue;
  541. X
  542. X/*
  543. X *    XON8250_ISR - This is the interrupt handler for the
  544. X *                    National Semiconducter 8250 Serial Chip.
  545. X *                    After installation by Catch_Rt, it catches the
  546. X *                    8250 interrupts and en_queues incoming characters
  547. X *                    from the Serial Port - and de-queues outgoing
  548. X *                    characters to the Serial Port.  The original code
  549. X *                    was written in assembler and provided about 80%
  550. X *                    of the Port's Bandwidth at 9600 baud running
  551. X *                    An Xmodem protocol.  We'll see what this does...
  552. X */
  553. X
  554. X#if (!defined (DLC))
  555. void    (interrupt far * xon_save_vec) (void);
  556. void interrupt far 
  557. xon8250_isr (void)
  558. X#else
  559. int 
  560. xon8250_isr ()
  561. X#endif
  562. X{
  563. X    int     ch;
  564. X    char    test_status;
  565. X
  566. X    enable ();
  567. X    test_status = inbyte ((XON_PORT_address + IIR));
  568. X    do
  569. X    {
  570. X        switch (test_status)
  571. X        {
  572. X            case IIR_rls:
  573. X                XON_PORT_status |= inbyte ((XON_PORT_address + LSR));
  574. X                break;
  575. X
  576. X            case IIR_receive:
  577. X                ch = inbyte (XON_PORT_address);
  578. X                if ((xoff_enabled && !xoff_sent) &&
  579. X                    (ch == XOFF_char))
  580. X                {
  581. X                    xoff_received = TRUE;
  582. X                }
  583. X                else
  584. X                    if (xoff_received &&
  585. X                        (ch == XON_char))
  586. X                {
  587. X                    xoff_received = FALSE;
  588. X                    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_TX_enable);
  589. X                }
  590. X                else
  591. X                    if ((en_queue (xon8250_inqueue, ch) < 10) &&
  592. X                        xoff_enabled && !xoff_sent && !xoff_received)
  593. X                {
  594. X                    xoff_sent = TRUE;
  595. X                    while ((inbyte ((XON_PORT_address + LSR)) & 0x20) == 0)
  596. X                        ;
  597. X                    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_TX_enable);
  598. X                    outbyte (XON_PORT_address, XOFF_char);
  599. X                }
  600. X                break;
  601. X
  602. X            case IIR_transmit:
  603. X                if (xoff_sent && (queue_avail (xon8250_inqueue) > 20))
  604. X                {
  605. X                    xoff_sent = FALSE;
  606. X                    outbyte (XON_PORT_address, XON_char);
  607. X                }
  608. X                else
  609. X                if (xoff_received)
  610. X                    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_enable);
  611. X                else
  612. X                if ((ch = de_queue (xon8250_outqueue)) != -1)
  613. X                {
  614. X                    outbyte (XON_PORT_address, ch);
  615. X                }
  616. X                else
  617. X                {
  618. X                    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_enable);
  619. X                }
  620. X                break;
  621. X
  622. X            case IIR_mstatus:
  623. X                test_status = inbyte ((XON_PORT_address + MSR));
  624. X                break;
  625. X        }
  626. X    } while ((test_status = inbyte (XON_PORT_address + IIR)) != IIR_complete);
  627. X    disable ();
  628. X    outbyte (INT_cntrl, EOI_word);
  629. X#if (defined (DLC))
  630. X    return (1);
  631. X#endif
  632. X}
  633. X
  634. X
  635. X
  636. X
  637. X/*
  638. X *    XON8250_INIT - Here we get the address of the 8250 Port
  639. X *                    which corresponds to the channel passed in.
  640. X *                    We then massage the 8259 Interrupt Controller
  641. X *                    calculate the Physical Interrupt and save off
  642. X *                    the 8250's current contents.  Then attach the
  643. X *                    xon8250_isr routine to the interrupt and
  644. X *                    return the rt returned index for saving - it's
  645. X *                    needed to terminate the interrupt.
  646. X */
  647. X
  648. X#define XON8250_STACK_SIZE 512
  649. int        xon8250_intno;
  650. static int xon_intmask [] = { 0xef, 0xf7, 0xef, 0xf7 };
  651. X/*
  652. X * The above 8259 mask bits are determined from the formula
  653. X *          mask = ~(1 << (5 - PORT_CHANNEL));
  654. X * The array assumes that COM3 and COM4 use the same interrupts
  655. X * as COM1 and COM2.
  656. X */
  657. static int xon_intno   [] = { 12, 11, 12, 11 };
  658. X/*
  659. X * The above interrupt number array is based on the algorithm
  660. X *       xon8250_intno = (13 - PORT_channel);
  661. X */
  662. X
  663. X
  664. int 
  665. xon8250_init (int channel, int buffer_size)
  666. X{
  667. X    int     Dos_address, mask;
  668. X    XON_PORT_channel = channel;
  669. X    xon8250_inqueue = alloc_queue (buffer_size);
  670. X    xon8250_outqueue = alloc_queue (buffer_size);
  671. X    Dos_address = (XON_PORT_channel - 1) * 2;
  672. X    peekmem (0x40, Dos_address, XON_PORT_address);
  673. X    mask = xon_intmask [XON_PORT_channel-1];
  674. X    SAVE_int_mask = inbyte (INT_mask);
  675. X    mask &= SAVE_int_mask;
  676. X    xon8250_intno = xon_intno [XON_PORT_channel-1];
  677. X    LCR_save = inbyte (XON_PORT_address + LCR);
  678. X    disable ();
  679. X    outbyte (XON_PORT_address + LCR, LCR_save | LCR_DLAB);
  680. X    MCR_save = inbyte (XON_PORT_address + MCR);
  681. X    DL_lsb = inbyte (XON_PORT_address);
  682. X    DL_msb = inbyte (XON_PORT_address + 1);
  683. X    outbyte (XON_PORT_address + LCR, LCR_save & 0x7F);
  684. X    IER_save = inbyte (XON_PORT_address + IER);
  685. X    enable ();
  686. X#if (defined (DLC))
  687. X    int_intercept (xon8250_intno, &xon8250_isr, XON8250_STACK_SIZE);
  688. X#else
  689. X    xon_save_vec = getvect (xon8250_intno);
  690. X    setvect (xon8250_intno, xon8250_isr);
  691. X#endif
  692. X    DELAY_init ();
  693. X    outbyte (INT_mask, mask);
  694. X}
  695. X
  696. X
  697. X
  698. X
  699. X/*
  700. X *    XON8250_TERM - This routine restores the rs232xon 8250 back to its
  701. X *                    state before xon8250_INIT was called and releases the
  702. X *                    corresponding interrupt back to the system.
  703. X */
  704. X
  705. void 
  706. xon8250_term (int restore)
  707. X{ 
  708. X    disable ();
  709. X    outbyte (INT_mask, SAVE_int_mask);
  710. X    if (restore)
  711. X    {
  712. X        outbyte (XON_PORT_address + LCR, LCR_DLAB);
  713. X        outbyte (XON_PORT_address, DL_lsb);
  714. X        outbyte (XON_PORT_address + 1, DL_msb);
  715. X        outbyte (XON_PORT_address + MCR, MCR_save);
  716. X        outbyte (XON_PORT_address + LCR, 0x7F);
  717. X        outbyte (XON_PORT_address + IER, IER_save);
  718. X        outbyte (XON_PORT_address + LCR, LCR_save);
  719. X    }
  720. X#if (defined (DLC))
  721. X    int_restore (xon8250_intno);
  722. X#else
  723. X    setvect (xon8250_intno, xon_save_vec);
  724. X#endif
  725. X}
  726. X
  727. X
  728. X
  729. X
  730. X/*
  731. X *    XON8250_READ - this routine looks in the xon8250_inqueue for a character
  732. X */
  733. X
  734. int 
  735. xon8250_read (void)
  736. X{
  737. X    int     ch;
  738. X    disable ();
  739. X    ch = de_queue (xon8250_inqueue);
  740. X    enable ();
  741. X    if ((XON_PORT_command == RX_enable) &&
  742. X        ((!queue_empty (xon8250_outqueue)) || xoff_sent))
  743. X        outbyte (XON_PORT_address + IER, XON_PORT_command = RX_TX_enable);
  744. X    return (ch);
  745. X}
  746. X
  747. X
  748. X
  749. X
  750. X/*
  751. X *    XON8250_TIMED_READ - attempts to read rs232 port - if no char
  752. X *                          available in number of seconds passed
  753. X *                          returns -1
  754. X */
  755. X
  756. int 
  757. xon8250_timed_read (int sec)
  758. X{
  759. X    int     ch;
  760. X
  761. X    timer_set ();
  762. X    while ((ch = xon8250_read ()) == -1)
  763. X        if ((timer_read () / 18) > sec)
  764. X            break;
  765. X    return (ch);
  766. X}
  767. X
  768. X
  769. X
  770. X
  771. X/*
  772. X *    XON8250_WRITE - plain vanilla write to the port - check to see that
  773. X *                     the chip may need a kick in the pants before returning
  774. X */
  775. X
  776. int 
  777. xon8250_write (char ch)
  778. X{
  779. X    int     rval = -1;
  780. X    disable ();
  781. X    rval = en_queue (xon8250_outqueue, ch);
  782. X    enable ();
  783. X    if (XON_PORT_command != RX_TX_enable)
  784. X        outbyte (XON_PORT_address + IER, XON_PORT_command = RX_TX_enable);
  785. X    return (rval);
  786. X}
  787. X
  788. X
  789. X
  790. X
  791. X/*
  792. X *    XON8250_DTRNR - drop Data Terminal Ready Line
  793. X */
  794. void
  795. xon8250_dtnr (void)
  796. X{
  797. X    char mcr_save;
  798. X    disable ();
  799. X    mcr_save = inbyte (XON_PORT_address + MCR);
  800. X    outbyte (XON_PORT_address + MCR, 0);
  801. X    DELAY_loop (500);
  802. X    outbyte (XON_PORT_address + MCR, mcr_save);
  803. X    enable ();
  804. X}
  805. X
  806. X
  807. X
  808. X
  809. X/*
  810. X *    XON8250_GET_STATUS - returns the current rs232xon status and
  811. X *                          resets any error condition.
  812. X */
  813. X
  814. int 
  815. xon8250_get_status (void)
  816. X{
  817. X    char    rval = XON_PORT_status;
  818. X    XON_PORT_status &= ERROR_reset;
  819. X    return ((int) rval);
  820. X}
  821. X
  822. X
  823. X
  824. X
  825. X/*
  826. X *    XON8250_XOFF_SENT - did we send an Xoff char?
  827. X */
  828. X
  829. int 
  830. xon8250_xoff_sent (void)
  831. X{
  832. X    return (xoff_sent);
  833. X}
  834. X
  835. X
  836. X
  837. X
  838. X
  839. X/*
  840. X *    XON8250_WRITE_BUFFER_EMPTY
  841. X */
  842. X
  843. xon8250_write_buffer_empty (void)
  844. X{
  845. X    return (queue_empty (xon8250_outqueue));
  846. X}
  847. X
  848. X
  849. X
  850. X
  851. X
  852. X/*
  853. X *    IOCTL_SET_XOFF
  854. X *    sets the rs232 xon/xoff    protocol.  It accepts a command string
  855. X *    of the form
  856. X *                 "y n" or "n n" or "n y" or "y y" either upper or
  857. X *                 lower case.
  858. X *    The 1st char enables or disables xon/xoff receive...
  859. X *    the 2d char enables or disables xon/xoff transmit
  860. X */
  861. X
  862. int 
  863. ioctl_set_xoff (char *cmd)
  864. X{
  865. X    char    temp;
  866. X    char    xrcv[2];
  867. X    sscanf (cmd, "%1s", xrcv);
  868. X    disable ();
  869. X    xoff_enabled = (toupper (*xrcv) == 'Y') ? TRUE : FALSE;
  870. X    enable ();
  871. X}
  872. X
  873. X
  874. X
  875. X
  876. X/*
  877. X *    XON8250_WRITE_BREAK - Write a BREAK Character
  878. X */
  879. X
  880. void 
  881. xon8250_write_break (void)
  882. X{
  883. X    int     i;
  884. X    disable ();
  885. X    while ((inbyte (XON_PORT_address + LSR) & 0x40) == 0)
  886. X        ;
  887. X    outbyte (XON_PORT_address + LCR, inbyte (XON_PORT_address + LCR) | 0x40);
  888. X    DELAY_loop (500);
  889. X    outbyte (XON_PORT_address + LCR, inbyte (XON_PORT_address + LCR) & 0xBF);
  890. X    enable ();
  891. X}
  892. X
  893. X
  894. X
  895. X
  896. X
  897. X/*
  898. X *    XON8250_XON_PORT_INIT (Cmd) configures the 8250
  899. X *        cmd is a string of the form baud parity stop data xon/xoff... i.e.
  900. X *        300 n 1 8 y
  901. X *
  902. X *        baud - 300, 600, 1200, 2400, 4800, 9600, 19200
  903. X *        parity - n -> no parity check
  904. X *                 o -> odd parity
  905. X *                 e -> even parity
  906. X *        stop   - 1 -> 1 stop bit
  907. X *                 2 -> 2 stop bits
  908. X *        data   - 5, 6, 7, 8 data bits
  909. X */
  910. X
  911. int 
  912. xon8250_port_init (char *cmd)
  913. X{
  914. X    unsigned baud, data, mode_word, parity, stop, xoff;
  915. X    char    pty[2];
  916. X    sscanf (cmd, "%d %1s %d %d", &baud, pty, &stop, &data);
  917. X    *pty = toupper (*pty);
  918. X    switch (*pty)
  919. X    {
  920. X        case 'E':
  921. X            parity = 1;
  922. X            break;
  923. X        case 'O':
  924. X            parity = 3;
  925. X            break;
  926. X        case 'N':
  927. X            parity = 0;
  928. X            break;
  929. X        default:
  930. X            parity = 0;
  931. X            break;
  932. X    }
  933. X    stop = (--stop & 1);
  934. X    stop <<= 2;
  935. X    baud /= 10;
  936. X    baud = 11520 / baud;
  937. X    parity <<= 3;
  938. X    parity &= 0x018;
  939. X    data -= 5;
  940. X    data &= 3;
  941. X    mode_word = data | stop | parity;
  942. X    disable ();
  943. X    xoff_received = FALSE;
  944. X    outbyte (XON_PORT_address + LCR, inbyte (XON_PORT_address + LCR) | LCR_DLAB);
  945. X    outbyte (XON_PORT_address, baud % 256);
  946. X    outbyte (XON_PORT_address + 1, baud / 256);
  947. X    outbyte (XON_PORT_address + LCR, mode_word & 0x7F);
  948. X    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_enable);
  949. X    outbyte (XON_PORT_address + MCR, 0x0F);
  950. X
  951. X    inbyte (XON_PORT_address + LSR);
  952. X    inbyte (XON_PORT_address + MSR);
  953. X    inbyte (XON_PORT_address);
  954. X    enable ();
  955. X}
  956. X
  957. X
  958. X
  959. X
  960. X/*---------------------- xon8250_port_enable () ----------------------*/
  961. X/*
  962. X *
  963. X */
  964. void
  965. xon8250_port_enable (void)
  966. X{
  967. X    disable ();
  968. X    outbyte (XON_PORT_address + IER, XON_PORT_command = RX_enable);
  969. X    outbyte (XON_PORT_address + MCR, 0x0F);
  970. X
  971. X    inbyte (XON_PORT_address + LSR);
  972. X    inbyte (XON_PORT_address + MSR);
  973. X    inbyte (XON_PORT_address);
  974. X    enable ();
  975. X}
  976. END_OF_FILE
  977. if test 12190 -ne `wc -c <'8250xon.c'`; then
  978.     echo shar: \"'8250xon.c'\" unpacked with wrong size!
  979. fi
  980. # end of '8250xon.c'
  981. fi
  982. if test -f '_kb.c' -a "${1}" != "-c" ; then 
  983.   echo shar: Will not clobber existing file \"'_kb.c'\"
  984. else
  985. echo shar: Extracting \"'_kb.c'\" \(4794 characters\)
  986. sed "s/^X//" >'_kb.c' <<'END_OF_FILE'
  987. X/*
  988. X *                               _KB.C
  989. X *
  990. X *                        Keyboard i/o Handler
  991. X *
  992. X *                           Written for the
  993. X *
  994. X *                              Datalight
  995. X *                           Microsoft V 5.x
  996. X *                                TurboC
  997. X *                                  &
  998. X *                               Zortech
  999. X *
  1000. X *                             C Compilers
  1001. X *
  1002. X *            Copyright (c) John Birchfield 1987, 1988, 1989
  1003. X */
  1004. X/*
  1005. X * If we use the Microsoft Compiler, we need to bind in MSC.OBJ
  1006. X * which contains the function _kbhit ().
  1007. X */
  1008. X
  1009. X#include <dos.h>
  1010. X
  1011. X/*
  1012. X *    defines for the bits returned in regs.x.cflag and by int86 () ...
  1013. X */
  1014. X
  1015. X#define ZERO_BIT       0x040
  1016. X#define CARRY_BIT          1
  1017. X#define SIGN_BIT       0x080
  1018. X#define DIRECTION_FLAG 0x400
  1019. X#define OVERFLOW_BIT   0x800
  1020. X
  1021. static union REGS regs;
  1022. X
  1023. X
  1024. X/*
  1025. X *    The following Translate Table is used to convert the PC scan
  1026. X *    codes into something of use.  The translated values are defined in
  1027. X *    the file "scr_iokb.h".
  1028. X */
  1029. X
  1030. X#include "_kb.h"
  1031. static struct xlate_tbl
  1032. X{
  1033. X    int     in, out;
  1034. X}       cvt[] =
  1035. X
  1036. X{
  1037. X    {
  1038. X                72, up_char
  1039. X    }      ,
  1040. X    {
  1041. X                80, down_char
  1042. X    }      ,
  1043. X    {
  1044. X                75, left_char
  1045. X    }      ,
  1046. X    {
  1047. X                77, right_char
  1048. X    }      ,
  1049. X    {
  1050. X                115, ctl_lft_char
  1051. X    }      ,
  1052. X    {
  1053. X                116, ctl_rt_char
  1054. X    }      ,
  1055. X    {
  1056. X                71, home_char
  1057. X    }      ,
  1058. X    {
  1059. X                79, end_char
  1060. X    }      ,
  1061. X    {
  1062. X                119, ctl_home_char
  1063. X    }      ,
  1064. X    {
  1065. X                117, ctl_end_char
  1066. X    }      ,
  1067. X    {
  1068. X                73, pageup_char
  1069. X    }      ,
  1070. X    {
  1071. X                81, pagedown_char
  1072. X    }      ,
  1073. X    {
  1074. X                132, ctl_pu_char
  1075. X    }      ,
  1076. X    {
  1077. X                118, ctl_pd_char
  1078. X    }      ,
  1079. X    {
  1080. X                82, Ins_char
  1081. X    }      ,
  1082. X    {
  1083. X                83, Del_char
  1084. X    }      ,
  1085. X
  1086. X    /* Straight Ahead Function Keys */
  1087. X    {
  1088. X                59, M1
  1089. X    }      ,
  1090. X    {
  1091. X                60, M2
  1092. X    }      ,
  1093. X    {
  1094. X                61, M3
  1095. X    }      ,
  1096. X    {
  1097. X                62, M4
  1098. X    }      ,
  1099. X    {
  1100. X                63, M5
  1101. X    }      ,
  1102. X    {
  1103. X                64, M6
  1104. X    }      ,
  1105. X    {
  1106. X                65, M7
  1107. X    }      ,
  1108. X    {
  1109. X                66, M8
  1110. X    }      ,
  1111. X    {
  1112. X                67, M9
  1113. X    }      ,
  1114. X    {
  1115. X                68, M10
  1116. X    }      ,
  1117. X
  1118. X    /* Shifted Function Keys */
  1119. X    {
  1120. X                104, M11
  1121. X    }      ,
  1122. X    {
  1123. X                105, M12
  1124. X    }      ,
  1125. X    {
  1126. X                106, M13
  1127. X    }      ,
  1128. X    {
  1129. X                107, M14
  1130. X    }      ,
  1131. X    {
  1132. X                108, M15
  1133. X    }      ,
  1134. X    {
  1135. X                109, M16
  1136. X    }      ,
  1137. X    {
  1138. X                110, M17
  1139. X    }      ,
  1140. X    {
  1141. X                111, M18
  1142. X    }      ,
  1143. X    {
  1144. X                112, M19
  1145. X    }      ,
  1146. X    {
  1147. X                113, M20
  1148. X    }      ,
  1149. X
  1150. X    /* Alt Function Keys */
  1151. X    {
  1152. X                84, M21
  1153. X    }      ,
  1154. X    {
  1155. X                85, M22
  1156. X    }      ,
  1157. X    {
  1158. X                86, M23
  1159. X    }      ,
  1160. X    {
  1161. X                87, M24
  1162. X    }      ,
  1163. X    {
  1164. X                88, M25
  1165. X    }      ,
  1166. X    {
  1167. X                89, M26
  1168. X    }      ,
  1169. X    {
  1170. X                90, M27
  1171. X    }      ,
  1172. X    {
  1173. X                91, M28
  1174. X    }      ,
  1175. X    {
  1176. X                92, M29
  1177. X    }      ,
  1178. X    {
  1179. X                93, M30
  1180. X    }      ,
  1181. X
  1182. X    /* Ctrl Function Keys */
  1183. X    {
  1184. X                94, M31
  1185. X    }      ,
  1186. X    {
  1187. X                95, M32
  1188. X    }      ,
  1189. X    {
  1190. X                96, M33
  1191. X    }      ,
  1192. X    {
  1193. X                97, M34
  1194. X    }      ,
  1195. X    {
  1196. X                98, M35
  1197. X    }      ,
  1198. X    {
  1199. X                99, M36
  1200. X    }      ,
  1201. X    {
  1202. X                100, M37
  1203. X    }      ,
  1204. X    {
  1205. X                101, M38
  1206. X    }      ,
  1207. X    {
  1208. X                102, M39
  1209. X    }      ,
  1210. X    {
  1211. X                103, M40
  1212. X    }      ,
  1213. X
  1214. X    {
  1215. X                0, 255
  1216. X    }
  1217. X};
  1218. X
  1219. X
  1220. X
  1221. X
  1222. X/*
  1223. X *    _KB can tell if the Keyboard has been touched.  If it has, he returns
  1224. X *        the value of the key pressed.  If the Control Key or one of the
  1225. X *        Numeric or Function Keys is pressed that value is returned
  1226. X *        from a look-up table.
  1227. X *
  1228. X *    Usage: if ((ch=_kb ())!=-1) we_have_a_char=TRUE;
  1229. X */
  1230. X
  1231. X
  1232. int 
  1233. X_kb ()
  1234. X{
  1235. X    int     ix, flag;
  1236. X#if (defined (DLC))
  1237. X# if (defined (__ZTC__))
  1238. X    if (kbhit ())
  1239. X# else
  1240. X    regs.h.ah = 1;
  1241. X    if ((int86 (0x16, ®s, ®s) & ZERO_BIT) == 0)
  1242. X# endif 
  1243. X    {
  1244. X#else
  1245. X# if (defined (__TURBOC__))
  1246. X    regs.h.ah = 1;
  1247. X    int86 (0x16, ®s, ®s);
  1248. X    if ((regs.x.flags & ZERO_BIT) == 0)
  1249. X    {
  1250. X# else
  1251. X    if (_kbhit ())
  1252. X    {
  1253. X# endif
  1254. X#endif
  1255. X        regs.h.ah = 0;
  1256. X        int86 (0x16, ®s, ®s);
  1257. X        if (regs.h.al == 0)
  1258. X        {
  1259. X            for (ix = 0; cvt[ix].in; ix++)
  1260. X                if (cvt[ix].in == regs.h.ah)
  1261. X                    break;
  1262. X            return (cvt[ix].out);
  1263. X        }
  1264. X        return ((int) regs.h.al);
  1265. X    }
  1266. X    return (-1);
  1267. X}
  1268. END_OF_FILE
  1269. if test 4794 -ne `wc -c <'_kb.c'`; then
  1270.     echo shar: \"'_kb.c'\" unpacked with wrong size!
  1271. fi
  1272. # end of '_kb.c'
  1273. fi
  1274. if test -f 'options.c' -a "${1}" != "-c" ; then 
  1275.   echo shar: Will not clobber existing file \"'options.c'\"
  1276. else
  1277. echo shar: Extracting \"'options.c'\" \(4538 characters\)
  1278. sed "s/^X//" >'options.c' <<'END_OF_FILE'
  1279. X/*
  1280. X *                              OPTIONS.C
  1281. X *
  1282. X *                           Written for the
  1283. X *
  1284. X *                              Datalight
  1285. X *                           Microsoft V 5.x
  1286. X *                                TurboC
  1287. X *                                  &
  1288. X *                               Zortech
  1289. X *
  1290. X *                             C Compilers
  1291. X *
  1292. X *            Copyright (c) John Birchfield 1987, 1988, 1989
  1293. X */
  1294. X
  1295. X#include <stdio.h>
  1296. X#include "options.h"
  1297. X
  1298. X#if (!defined (TRUE))
  1299. X#    define TRUE  (1)
  1300. X#    define FALSE (0)
  1301. X#endif
  1302. X
  1303. int     Port = 1;
  1304. X
  1305. char    Opt_Msg [159] = { 0 },
  1306. X        Baud_rate[] = "1200",
  1307. X        Parity[] = "N",
  1308. X        Data[] = "8",
  1309. X        Stop[] = "1",
  1310. X
  1311. X        Cfg_Str[15] = { 0 };
  1312. X
  1313. X
  1314. int  good_baud (char *);
  1315. void usage (void);
  1316. X
  1317. void 
  1318. set_options (int cnt, char **args)
  1319. X{
  1320. X    char   *ch;
  1321. X    int   c_flag = 0;
  1322. X    while (--cnt > 0)
  1323. X    {
  1324. X        ch = *++args;
  1325. X        if (*ch == '?')
  1326. X            usage ();
  1327. X        if (*ch == '-')
  1328. X            switch (toupper (*++ch))
  1329. X            {
  1330. X                case 'C':
  1331. X                    switch (*++ch)
  1332. X                    {
  1333. X                        case '1':
  1334. X                            Port = 1;
  1335. X                            break;
  1336. X                        case '2':
  1337. X                            Port = 2;
  1338. X                            break;
  1339. X                        default:
  1340. X                            usage ();
  1341. X                            break;
  1342. X                    }
  1343. X                    break;
  1344. X                case 'B':
  1345. X                    c_flag = TRUE;
  1346. X                    if (good_baud (++ch))
  1347. X                        strcpy (Baud_rate, ch);
  1348. X                    else
  1349. X                        usage ();
  1350. X                    break;
  1351. X                case 'P':
  1352. X                    c_flag = TRUE;
  1353. X                    switch (toupper (*++ch))
  1354. X                    {
  1355. X                        case 'E':
  1356. X                            Parity[0] = 'E';
  1357. X                            break;
  1358. X                        case 'O':
  1359. X                            Parity[0] = 'O';
  1360. X                            break;
  1361. X                        case 'N':
  1362. X                            Parity[0] = 'N';
  1363. X                            break;
  1364. X                        default:
  1365. X                            usage ();
  1366. X                            break;
  1367. X                    }
  1368. X                    break;
  1369. X                case 'S':
  1370. X                    c_flag = TRUE;
  1371. X                    switch (*++ch)
  1372. X                    {
  1373. X                        case '1':
  1374. X                            Stop[0] = '1';
  1375. X                            break;
  1376. X                        case '2':
  1377. X                            Stop[0] = '2';
  1378. X                            break;
  1379. X                        default:
  1380. X                            usage ();
  1381. X                            break;
  1382. X                    }
  1383. X                    break;
  1384. X                case 'D':
  1385. X                    c_flag = TRUE;
  1386. X                    switch (*++ch)
  1387. X                    {
  1388. X                        case '7':
  1389. X                        case '8':
  1390. X                            Data[0] = *ch;
  1391. X                            break;
  1392. X                        default:
  1393. X                            usage ();
  1394. X                            break;
  1395. X                    }
  1396. X                    break;
  1397. X                default:
  1398. X                    break;
  1399. X            }
  1400. X    }
  1401. X    if (c_flag)
  1402. X    {
  1403. X        sprintf (Opt_Msg, "%s %d %s%s%s %s%s %s%s %s%s\n",
  1404. X                          "Com Port", Port, "Initialized  %--%  ",
  1405. X                          "   Baud=", Baud_rate, "Parity=", Parity,
  1406. X                          "Data=", Data, "Stop=", Stop);
  1407. X        strcpy (Cfg_Str, Baud_rate);
  1408. X        strcat (Cfg_Str, " ");
  1409. X        strcat (Cfg_Str, Parity);
  1410. X        strcat (Cfg_Str, " ");
  1411. X        strcat (Cfg_Str, Stop);
  1412. X        strcat (Cfg_Str, " ");
  1413. X        strcat (Cfg_Str, Data);
  1414. X    }
  1415. X}
  1416. X
  1417. X
  1418. X
  1419. X
  1420. X
  1421. static char *baud_rates[] =
  1422. X{
  1423. X "300", "600", "1200", "2400", "4800", "9600", "19200", 0
  1424. X};
  1425. X
  1426. int 
  1427. good_baud (char *s)
  1428. X{
  1429. X    int     i;
  1430. X    for (i = 0; baud_rates [i]; i++)
  1431. X        if (strcmp (baud_rates[i], s) == 0)
  1432. X            return (TRUE);
  1433. X    return (0);
  1434. X}
  1435. X
  1436. X
  1437. X
  1438. void
  1439. usage (void)
  1440. X{
  1441. X    fputs ("Use the following command line options.\n\n", stderr);
  1442. X    fputs ("   -C[1 or 2] Com Port 1 or 2      {Default Com Port 1}\n", stderr);
  1443. X    fputs ("   -B[300 600 1200 2400 4800 9600] {Default 9600 Baud}\n", stderr);
  1444. X    fputs ("   -D[7 or 8]  Data Bits           {Default 8}\n", stderr);
  1445. X    fputs ("   -S[1 or 2] Stop Bits            {Default 1}\n", stderr);
  1446. X    fputs ("   -P[E O or N] Parity             {Default None}\n\n", stderr);
  1447. X    fputs ("   -b2400 -pn -s1 -d8 -c1\n\n", stderr);
  1448. X    exit (1);
  1449. X}
  1450. X
  1451. END_OF_FILE
  1452. if test 4538 -ne `wc -c <'options.c'`; then
  1453.     echo shar: \"'options.c'\" unpacked with wrong size!
  1454. fi
  1455. # end of 'options.c'
  1456. fi
  1457. if test -f 'screen.c' -a "${1}" != "-c" ; then 
  1458.   echo shar: Will not clobber existing file \"'screen.c'\"
  1459. else
  1460. echo shar: Extracting \"'screen.c'\" \(9082 characters\)
  1461. sed "s/^X//" >'screen.c' <<'END_OF_FILE'
  1462. X/*
  1463. X *                              SCREEN.C
  1464. X *
  1465. X *                         Screen i/o Handler
  1466. X *
  1467. X *                           Written for the
  1468. X *
  1469. X *                              Datalight
  1470. X *                           Microsoft V 5.x
  1471. X *                                TurboC
  1472. X *                                  &
  1473. X *                               Zortech
  1474. X *
  1475. X *                             C Compilers
  1476. X *
  1477. X *            Copyright (c) John Birchfield 1987, 1988, 1989
  1478. X */
  1479. X
  1480. X#include <dos.h>
  1481. X#include "screen.h"
  1482. X/*
  1483. X *    defines for the bits returned in regs.x.cflag and by int86 () ...
  1484. X */
  1485. X
  1486. X#define ZERO_BIT       0x040
  1487. X#define CARRY_BIT          1
  1488. X#define SIGN_BIT       0x080
  1489. X#define DIRECTION_FLAG 0x400
  1490. X#define OVERFLOW_BIT   0x800
  1491. static union REGS regs;
  1492. X
  1493. X
  1494. X
  1495. X#define VIDEO        0x10    /* interrupt for dealing with screen */
  1496. X#define MODE         0      /* code for setting new screen mode */
  1497. X#define SETCURTYP     1      /* code for setting new cursor type */
  1498. X#define SETCURSOR     2      /* code for addressing cursor */
  1499. X#define GETCURSOR     3      /* code for reading cursor location */
  1500. X#define READLP         4      /* code for reading light pen position */
  1501. X#define SETPAGE         5      /* code to select active page */
  1502. X#define SCROLLUP     6      /* code to scroll screen up */
  1503. X#define SCROLLDN     7      /* code to scroll screen nown */
  1504. X#define READCH         8      /* code to read a character from screen */
  1505. X#define WRITEACH     9      /* code to write char and attributes */
  1506. X#define WRITECH        10      /* code to write character only */
  1507. X#define SETPAL        11      /* code to set new setpal or border */
  1508. X#define WDOT        12      /* code to write a dot */
  1509. X#define RDOT        13      /* code to read a dot */
  1510. X#define WRITETTY    14      /* code to write as if teletype */
  1511. X#define STATE        15      /* code to find current screen status */
  1512. X
  1513. X
  1514. X/*
  1515. X *    note- make 25 for ms-dos and 24 for cp/m as cp/m steals the bottom
  1516. X *    line.
  1517. X */
  1518. X
  1519. int     Scr_Rows = 25;  /* current number of rows */
  1520. int     Scr_Cols = 80;  /* current number of columns */
  1521. char    Scr_Mode = 0;   /* current screen mode */
  1522. char    Scr_Page = 0;   /* current page */
  1523. char    Scr_ATTR = 7;   /* current attributes for screen 7 is white letters
  1524. X                         * on black    */
  1525. char    Scr_Window_Top = 0;     /* first line to scroll */
  1526. X
  1527. X
  1528. X
  1529. X/*
  1530. X *    SCREEN_INIT - screen_init must be called before any use of any
  1531. X *               other routine unless the starting mode is 80X25
  1532. X *             character mode (3,4 or 7). Must be called for
  1533. X *               monocrome (mode 7) for scr_curson to set a proper
  1534. X *               cursor.
  1535. X *
  1536. X *    Usage:      screen_init ();
  1537. X */
  1538. X
  1539. int 
  1540. screen_init (void)
  1541. X{
  1542. X    regs.h.ah = STATE;
  1543. X    int86 (VIDEO, ®s, ®s);
  1544. X    Scr_Mode = regs.h.al;
  1545. X    Scr_Cols = regs.h.ah;
  1546. X    Scr_Page = regs.h.bh;
  1547. X    Scr_ATTR = (regs.h.al < 4 || regs.h.al == 7) ? 7 : 0;
  1548. X    return (regs.h.al);
  1549. X}
  1550. X
  1551. X
  1552. X
  1553. X
  1554. X/*
  1555. X *    SCREEN_SMODE - set a new screen mode
  1556. X *
  1557. X *    Usage:        screen_smode (new mode);
  1558. X */
  1559. X
  1560. int 
  1561. screen_smode (char newmode)
  1562. X{
  1563. X    regs.h.al = newmode;
  1564. X    regs.h.ah = MODE;
  1565. X    int86 (VIDEO, ®s, ®s);
  1566. X    screen_init ();
  1567. X}
  1568. X
  1569. X
  1570. X
  1571. X/*
  1572. X *    ROWCOL - sets cursor at any location.
  1573. X *
  1574. X *    Usage:       rowcol (new row, new column);
  1575. X */
  1576. X
  1577. int 
  1578. rowcol (int row, int col)
  1579. X{
  1580. X    regs.h.dl = col;
  1581. X    regs.h.dh = row;
  1582. X    regs.h.bh = Scr_Page;
  1583. X    regs.h.ah = SETCURSOR;
  1584. X    int86 (VIDEO, ®s, ®s);
  1585. X}
  1586. X
  1587. X
  1588. X
  1589. X/*
  1590. X *  G_ROWCOL - returns the current screen row and column
  1591. X *               the row is the high order 8 bits and the
  1592. X *               column is the low order.
  1593. X *
  1594. X *    Usage:     rowcol = g_rowcol ();
  1595. X *               cur_row = rowcol >> 8;
  1596. X *               cur_col = rowcol && 0xFF;
  1597. X */
  1598. X
  1599. int 
  1600. g_rowcol (void)
  1601. X{
  1602. X    regs.h.ah = GETCURSOR;
  1603. X    regs.h.bh = Scr_Page;
  1604. X    int86 (VIDEO, ®s, ®s);
  1605. X    return (regs.x.dx);
  1606. X}
  1607. X
  1608. X
  1609. X
  1610. X
  1611. X/*
  1612. X *    CLRSCRN - clear entire screen
  1613. X *
  1614. X *    Usage:    clrscrn ();
  1615. X */
  1616. X
  1617. int 
  1618. clrscrn (void)
  1619. X{
  1620. X    regs.h.al = 0;
  1621. X    regs.x.cx = 0;
  1622. X    regs.h.dh = Scr_Rows - 1;
  1623. X    regs.h.dl = Scr_Cols - 1;
  1624. X    regs.h.bh = Scr_ATTR;
  1625. X    regs.h.ah = SCROLLUP;
  1626. X    int86 (VIDEO, ®s, ®s);
  1627. X}
  1628. X
  1629. X
  1630. X
  1631. X
  1632. X/*
  1633. X *    CLEOL - clear to End Of Line
  1634. X *
  1635. X *    Usage:     cleol ();
  1636. X */
  1637. X
  1638. int 
  1639. cleol (void)
  1640. X{
  1641. X    regs.h.bh = Scr_Page;
  1642. X    regs.h.ah = GETCURSOR;
  1643. X    int86 (VIDEO, ®s, ®s);
  1644. X    regs.h.cl = Scr_Cols - regs.h.dl;
  1645. X    regs.h.ch = 0;
  1646. X    regs.h.al = ' ';
  1647. X    regs.h.bl = Scr_ATTR;
  1648. X    regs.h.bh = Scr_Page;
  1649. X    regs.h.ah = WRITEACH;
  1650. X    int86 (VIDEO, ®s, ®s);
  1651. X}
  1652. X
  1653. X
  1654. X
  1655. X
  1656. X/*
  1657. X *    CLEOP - clear to End Of Page
  1658. X *
  1659. X *    Usage:    cleop ();
  1660. X */
  1661. X
  1662. int 
  1663. cleop (void)
  1664. X{
  1665. X    cleol ();
  1666. X    regs.h.ah = GETCURSOR;
  1667. X    regs.h.bh = Scr_Page;
  1668. X    int86 (VIDEO, ®s, ®s);
  1669. X    regs.h.al = 0;
  1670. X    if ((regs.h.ch = regs.h.dh + 1) < Scr_Rows - 1)
  1671. X    {
  1672. X        regs.h.cl = 0;
  1673. X        regs.h.dh = Scr_Rows - 1;
  1674. X        regs.h.dl = Scr_Cols - 1;
  1675. X        regs.h.bh = Scr_ATTR;
  1676. X        regs.h.ah = SCROLLUP;
  1677. X        int86 (VIDEO, ®s, ®s);
  1678. X    }
  1679. X}
  1680. X
  1681. X
  1682. X
  1683. X/*
  1684. X *    SCROLL_UP - Scroll the screen up. The window is scrolled
  1685. X *                up nlines lines. A zero nlines will clear the
  1686. X *                window. Top left of the screen is 0,0.
  1687. X *
  1688. X *    Usage:      SCROLL_UP (nlines, start_row, start_col, end_row, end_col);
  1689. X */
  1690. X
  1691. int 
  1692. scroll_up (int nlines, 
  1693. X           int start_row, int start_col,
  1694. X           int end_row,   int end_col)
  1695. X{
  1696. X    regs.h.al = nlines;
  1697. X    regs.h.ch = start_row;
  1698. X    regs.h.cl = start_col;
  1699. X    regs.h.dh = end_row;
  1700. X    regs.h.dl = end_col;
  1701. X    regs.h.bh = Scr_ATTR;
  1702. X    regs.h.ah = SCROLLUP;
  1703. X    int86 (VIDEO, ®s, ®s);
  1704. X}
  1705. X
  1706. X
  1707. X
  1708. X/*
  1709. X *    SCROLL_DN - scroll the screen down. the window is scrolled
  1710. X *                down nline lines. A zero nline will clear the
  1711. X *                window. Top left of the screen in 0,0.
  1712. X *
  1713. X *    Usage:      scroll_dn (nlines,start_row, start_col, end_row, end_col);
  1714. X */
  1715. X
  1716. int 
  1717. scroll_dn (int nlines,
  1718. X           int start_row, int start_col,
  1719. X           int end_row,   int end_col)
  1720. X{
  1721. X    regs.h.al = nlines;
  1722. X    regs.h.ch = start_row;
  1723. X    regs.h.cl = start_col;
  1724. X    regs.h.dh = end_row;
  1725. X    regs.h.dl = end_col;
  1726. X    regs.h.bh = Scr_ATTR;
  1727. X    regs.h.ah = SCROLLDN;
  1728. X    int86 (VIDEO, ®s, ®s);
  1729. X}
  1730. X
  1731. X
  1732. X
  1733. X
  1734. X
  1735. X/*
  1736. X *    SCREEN_CO - write a character to the screen. this
  1737. X *                routine increments the cursor position
  1738. X *                after writing. normal C88 puts and printf
  1739. X *                statements can also be used to write to the
  1740. X *                screen.
  1741. X *
  1742. X *    Usage:   screen_co (character);
  1743. X */
  1744. X
  1745. int 
  1746. screen_co (char ch)
  1747. X{
  1748. X    regs.h.al = ch;
  1749. X    regs.h.bh = Scr_Page;
  1750. X    regs.h.ah = WRITETTY;
  1751. X    int86 (VIDEO, ®s, ®s);
  1752. X}
  1753. X
  1754. X
  1755. X
  1756. X
  1757. X/*
  1758. X *    SINP - screen input (read character from the screen).
  1759. X *
  1760. X *    Usage:     character = sinp ();
  1761. X */
  1762. X
  1763. int 
  1764. sinp (void)
  1765. X{
  1766. X    regs.h.bh = Scr_Page;
  1767. X    regs.h.ah = READCH;
  1768. X    int86 (VIDEO, ®s, ®s);
  1769. X    return ((int) (regs.h.al) ? regs.h.al : ' ');
  1770. X}
  1771. X
  1772. X
  1773. X
  1774. X
  1775. X
  1776. X/*
  1777. X *    CURSOR_OFF - turn cursor off.
  1778. X *
  1779. X *    Usage:        cursor_off ();
  1780. X */
  1781. X
  1782. int 
  1783. cursor_off (void)
  1784. X{
  1785. X    if (Scr_Mode < 4 || Scr_Mode == 7)
  1786. X    {
  1787. X        regs.x.cx = 0x0f00;
  1788. X        regs.h.ah = SETCURTYP;
  1789. X        int86 (VIDEO, ®s, ®s);
  1790. X    }
  1791. X}
  1792. X
  1793. X
  1794. X
  1795. X
  1796. X/*
  1797. X *    CURSOR_ON - turn cursor back on.
  1798. X *
  1799. X *    Usage:       cursor_on ();
  1800. X */
  1801. X
  1802. int 
  1803. cursor_on (void)
  1804. X{
  1805. X    if (Scr_Mode == 7)
  1806. X        regs.x.cx = 0x0C0D;
  1807. X    else
  1808. X    if (Scr_Mode < 4)
  1809. X        regs.x.cx = 0x0607;
  1810. X    else
  1811. X        return;
  1812. X    regs.h.ah = SETCURTYP;
  1813. X    int86 (VIDEO, ®s, ®s);
  1814. X}
  1815. X
  1816. X
  1817. X
  1818. X
  1819. X
  1820. X/*
  1821. X *    APUTS - write a string in the current attribute to the screen.
  1822. X *
  1823. X *    Usage:      aputs (attr, "Write this out\n");
  1824. X */
  1825. X
  1826. int 
  1827. aputs (int a, char *s)
  1828. X{
  1829. X    while (*s)
  1830. X        aput (a, *s++);
  1831. X}
  1832. X
  1833. X
  1834. X
  1835. X
  1836. X/*
  1837. X *    APUT - write a string and attributes to the screen.
  1838. X *               the cursor is moved normally
  1839. X *
  1840. X *    Usage:     aput (INVERSE, 'x');
  1841. X */
  1842. X
  1843. int 
  1844. aput (int attr, char ch)
  1845. X{
  1846. X    switch (ch)
  1847. X    {
  1848. X        default:
  1849. X            regs.h.al = ch;
  1850. X            regs.h.bl = attr;
  1851. X            regs.x.cx = 1;
  1852. X            regs.h.bh = Scr_Page;
  1853. X            regs.h.ah = WRITEACH;
  1854. X            int86 (VIDEO, ®s, ®s);
  1855. X            regs.h.ah = GETCURSOR;
  1856. X            int86 (VIDEO, ®s, ®s);
  1857. X            if (!(++regs.h.dl < Scr_Cols))
  1858. X            {
  1859. X                regs.h.dl = 0;
  1860. X                if (!(++regs.h.dh < Scr_Rows))
  1861. X                {
  1862. X                    scroll_up (1, 0, 0, 23, 79);
  1863. X                    regs.h.dl = 0;
  1864. X                    regs.h.dh = 23;
  1865. X                }
  1866. X            }
  1867. X            regs.h.bh = Scr_Page;
  1868. X            regs.h.ah = SETCURSOR;
  1869. X            int86 (VIDEO, ®s, ®s);
  1870. X            break;
  1871. X        case 10:
  1872. X            regs.h.ah = GETCURSOR;
  1873. X            int86 (VIDEO, ®s, ®s);
  1874. X            regs.h.dl = 0;
  1875. X            if (!(++regs.h.dh < Scr_Rows - 2))
  1876. X            {
  1877. X                scroll_up (0, 0, 0, Scr_Rows - 2, 79);
  1878. X                regs.h.dl = 0;
  1879. X                regs.h.dh = Scr_Rows - 2;
  1880. X            }
  1881. X            regs.h.bh = Scr_Page;
  1882. X            regs.h.ah = SETCURSOR;
  1883. X            int86 (VIDEO, ®s, ®s);
  1884. X            break;
  1885. X        case 13:
  1886. X            regs.h.ah = GETCURSOR;
  1887. X            int86 (VIDEO, ®s, ®s);
  1888. X            regs.h.dl = 0;
  1889. X            regs.h.bh = Scr_Page;
  1890. X            regs.h.ah = SETCURSOR;
  1891. X            int86 (VIDEO, ®s, ®s);
  1892. X            break;
  1893. X    }
  1894. X}
  1895. END_OF_FILE
  1896. if test 9082 -ne `wc -c <'screen.c'`; then
  1897.     echo shar: \"'screen.c'\" unpacked with wrong size!
  1898. fi
  1899. # end of 'screen.c'
  1900. fi
  1901. echo shar: End of archive 2 \(of 3\).
  1902. cp /dev/null ark2isdone
  1903. MISSING=""
  1904. for I in 1 2 3 ; do
  1905.     if test ! -f ark${I}isdone ; then
  1906.     MISSING="${MISSING} ${I}"
  1907.     fi
  1908. done
  1909. if test "${MISSING}" = "" ; then
  1910.     echo You have unpacked all 3 archives.
  1911.     rm -f ark[1-9]isdone
  1912. else
  1913.     echo You still need to unpack the following archives:
  1914.     echo "        " ${MISSING}
  1915. fi
  1916. ##  End of shell archive.
  1917. exit 0
  1918. +----------------------
  1919. | John Birchfield      
  1920. | jb@altair.csustan.edu
  1921. +----------------------
  1922.  
  1923.  
  1924.