Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 2311.07 Kb

Программирование и кодирование

Предыдущая страница Следующая страница
1 ... 122 123 124 125 126 127 128  129 130 131 132 133 134 135 ... 198
         #define MDMSTATUS   0
         #define TXREGEMPTY  2
         #define RXDATAREADY 4
         #define RLINESTATUS 6

         /* Флаги управления потоком XON/XOFF */
         #define XON_RCVD   1
         #define XOFF_RCVD  0
         #define XON_SENT   1
         #define XOFF_SENT  0

         /* Высший и низший коэффициенты для триггера xon-xoff */
         #define HI_TRIGGER(x)  (3*x/4)
         #define LO_TRIGGER(x)  (x/4)

         /* Функция получения нулевого бита целого */
         #define bit0(i)   (i & 0x0001)

         /* Макрокоманда для включения прерывания, "номер разрешения
          * прерывания" которого "i", в противном случае оно запрещает-
          * ся.  Например, прерывание THRE запрещается, если XOFF полу-
          * чен от удаленной системы.
          */

         #define turnon_int(i,j) \
                 if(((j=inp(IER))&i)==0)outp(IER,(j|i))

         #define report_error(s)  fprintf(stderr,s)
         typedef struct QTYPE  /* структура данных для очереди */
         {
                int  count;
                int  front;
                int  rear;
                int  mexsize;
                char *data;
         }   QTYPE;

         static char rxbuf[RXQSIZE], txbuf[TXQSIZE];

         static QTYPE rcvq = {0, }-1, -1, RXQSIZE, rxbuf},
                      trmq = {0, }-1, -1, TXQSIZE, txbuf};

         /* Признаки общего состояния */
         int s_linestatus, s_modemstatus;


                                      - 8-25 -
         static  QTYPE *txq = &trmq, *rxq = &rcvq;
         static  short comport=0,
                       enable_xonxoff = 1,
                       rcvd_xonxoff = XON_RCVD,
                       sent_xonxoff = XON_SENT,
                       send_xon = FALSE,
                       send_xoff = FALSE,
                       int_number = 12;
                       int_enable_mask = 0xef,
                       int_disable_mask = 0x10;

         /* Прототипы функций */
         int s_sendchar(int);
         int s_rcvchar(void);
         int s_setup(short, unsigned);
         int s_cleanup(void);

         char *q_getfrom( QTYPE *, char *);
         int   q_puton( QTYPE *, char *);

         void interrupt far s_inthndlr(void);

         static void  s_rda(void);
         static void  s_trmty(void);
         static void  (interrupt far *old_handler)();
         /*----------------------------------------------------------*/
         main(int argc, char **argv)
         {
             int ch, port_number = 0;

         /* Получить номер порта из командной строки */
             if(argc > 1) port_number = atoi(argv[1]) - 1;
             printf("\nSERIO -- Последовательный ввод/вывод \
         c параметрами 1200,8,N,1 через порт COM%d\n", port_number+1);
             printf("\nСвязь ...\n");

         /* Сначала установить последовательный порт */
             s_setup(port_number, COM_PARAMS);

         /* Последующий бесконечный цикл имитирует терминал.
          * Клавиша Escape служить для общего сброса и возврата.
          */

             while (TRUE)
             {
                  if ((ch = s_rcvchar()) != -1) putch(ch);
                  if ( kbhit() != 0)
                  {
                      ch = getch();
                      if (ch == ESC_KEY)
                      {
                            s_cleanup();
                            return;
                      }

                      else
                          s_sendchar(ch);

                                      - 8-26 -
                  }     /* конец проверки kbhit() */
             }
         }
         /*---------------------------------------------------------*/
         /* s _ i n t h n d l r
          * Обработчик всех прерываний последовательного порта.
          */
         void interrupt far s_inthndlr(void)
         {
             int c;
             registr int int_id, intmask;

         /* Немедленно разрешить прерывания */
             _enable();

             while (TRUE)
             {
         /* Считать регистр идентификации прерывания , IIR */
                int_id = inp(IIR);
                if (bit0(int_id) == 1)
                {
         /* Если бит 0 - 1, то прерывания не ожидаются. Направить прог-
          * раммируемому контроллеру прерываний сигнал  "конец прерыва-
          * ния" и вернуться.
          */
                    outp(P8259_0, END_OF_INT);
                    return;
                }
                if (int_id >= RXDATAREADY)
                                turnon_int(THREINT,intmask);
         /* Обработать прерывание в соответствии с идентификатором.
          * Следующий перечень составлен в соответствии с возрастанием
          * приоритета.
          */


                 switch (int_id)
                 {
                    case MDMSTATUS:    /* считать состояние модема */
                                       s_modemstatus = inp(MSR);
                                       break;
                    case TXREGEMPTY:   s_trmty();
                                       break;
                    case RXDATAREADY:  s_rda();
                                       break;
                    case RLINESTATUS:  /* читать состояние линии */
                                       s_linestatus = inp(LSR);
                                       break;
         /* пропустить, если идентификатор не является одним из
          * перечисленных */
                 }
             }
         }
         /*---------------------------------------------------------*/
         /* s _ r d a
          * Обработать прерывание "доступны данные для приема"
          */

                                      - 8-27 -
         static void s_rda(void)
         {
             registr int intmask;
             char c;
         /* читать из коммуникационного порта */
             c = inp(comport);
             if(enable_xonxoff) {
                if (c == XON_ASCII) {
                      rcvd_xonxoff = XON_RCVD;
         /* Включить прерывание THRE, если оно выключено. */
                      turnon_int(THREINT,intmask);
                      return;
                }
                if(c == XOFF_ASCII) {
                      rcvd_xonxoff = XOFF_RCVD;
         /* Сбросить прерывания THRE */

                      intmask = inp(IER);
                      if (intmask & THREINT)
                                outp(IER, intmask & THREOFF);
                      return;
                 }
             }
             q_puton(rxq, &c);
         /* Проверить, заполнена ли почти очередь (75%) */
             if(enable_xonxoff) {
                if(rxq->count >= HI_TRIGGER(RXQSIZE) &&
                   sent_xonxoff != XOFF_SENT ) {
         /* Установить флаг для направления XOFF */
                   send_xoff = TRUE;
         /* Включить прерывания THRE так, чтобы послать XOFF */
                   turnon_int(THREINT,intmask);
               }
            }
         }
         /*---------------------------------------------------------*/
         /* s _ t r m t y
          * Обработать прерывание "регистр хранения передачи
          * свободен"
          */
         static void s_trmty(void)
         {
             char c;
             registr int ierval;

             if (send_xoff == TRUE) {
                 outp(comport, XOFF_ASCII);
                 send_off = FALSE;
                 sent_xonxoff = XOFF_SENT;
                 return;
             }
             if (send_xon == TRUE) {
                 outp(comport, XON_ASCII);
                 send_xon = FALSE;

                 sent_xonxoff = XON_SENT;
                 return;

                                      - 8-28 -
             }
         /* Поместить символ в регистр хранения передачи */
             if( q_getfrom(txq, &c) != NULL){
                 outp(comport, c);
                 return;
             }
         /* Нечего посылать -- сбросить прерывания THRE */
             ierval = inp(IER);
             if (ierval & THREINT) outp(IER, ierval & THREOFF);
         }
         /*---------------------------------------------------------*/
         /* s _ s e t u p
          * Установить все для связи.
          * Вернуть 1, если установка прошла успешно, в противном
          * случае вернуть 0.
          */
         int s_setup(short port_number, unsigned commparams)
         {
             int intmask;

             if (port_number < 0 || port_number > 1)
                 report_error("Неверный номер порта!\n");

         /* Получить базовый адрес последовательного порта из
          * области данных BIOS */
             comport = *(BIOS_DATA + port_number);
             if (comport == 0)
             {
                 report_error("BIOS не может найти порт!\n");
                 return(0);
             }

         /* Установить маски для программируемого контроллера
          * прерываний 8259A. Для разрешения прерывания порта
          * эта маска логически умножается с маской регистра

          * в 21h. Для запрещения, логически сложить маску
          * запрещения с маской регистра. Номер прерывания
          * определяется как 8 + уровень IRQ прерывания.
          * Коммуникационный порт 1 имеет IRQ 4, порт 2 имеет
          * IRQ 3.
          */
             if (port_number == 0)
             {
                 int_enable_mask = 0xef;
                 int_disable_mask = 0x10;
                 int_number = 12;

             }
             if (port_number == 1)
             {
                 int_enable_mask = 0xf7;
                 int_disable_mask = 8;
                 int_number = 11;
             }

         /* Получить номер старого прерывания и сохранить его. */

                                      - 8-29 -
             old_handler = _dos_getvect(int_number);

         /* Установить новый обработчик с именем s_inthndlr.
          * Запретить прерывания при смене обработчика.
          */
             _disable();
             _dos_setvect(int_number, s_inthndlr);
             _enable();

         /* Установить коммуникационные параметры */
             _bios_serialcom(_COM_INIT, port_number, commparams);

         /* Инициализировать флаги XON/XOFF */
             rcvd_xonxoff = XON_RCVD;
             if (sent_xonxoff == XOFF_SENT)
                 send_xon = TRUE;

             else
                 send_xon = FALSE;
                 send_xoff = FALSE;

         /* Включить прерывания коммуникационного порта и
          * установка 8259A.
          */
             _disable();
         /* Установить регистр управления модемом (порт = MCR) */
             outp(MCR, MCRALL);

         /* Разрешить все прерывания последовательной карты */
             outp(IER, IERALL);

         /* Считать регистр маски прерывания 8259A и записать его
          * обратно после логического умножения с _int_enable_mask.
          */
             intmask = inp(P8259_1) & int_enable_mask;
             outp(P8259_1, intmask);

             _enable();

             return(1);
         }
         /*---------------------------------------------------------*/
         /* s _ c l e a n u p
         /* Очистить после сеанса связи. Сбросить все прерывания. */
         int s_cleanup(void)
         {
             int intmask;

         /* Выключить прерывания последовательной карты */
             _disable();
         /* Первым сбросить регистр разрешения прерывания порта */
             outp(IER, IEROFF);

         /* Сбросить все биты регистра управления модемом */
             outp(MCR, MCROFF);

         /* Затем запретить распознавание контроллером 8259A

                                      - 8-30 -
Предыдущая страница Следующая страница
1 ... 122 123 124 125 126 127 128  129 130 131 132 133 134 135 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама