Annotation of ntddk/src/vdd/com_vdd/pc_com.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * PC_com.c
        !             3:  *
        !             4:  * This module handles the virtual UART I/O and interrupt interface
        !             5:  *
        !             6:  * Note:
        !             7:  *  Refer to National Semiconductor literature for a detailed description
        !             8:  *  of the NS16450/NS8250A UART.  Refer to the PC-XT Tech Ref Manual 
        !             9:  *  Section 1-185 for a description of the Asynchronous Adaptor Card.
        !            10:  *
        !            11:  * copyright 1992 by Microsoft Corporation
        !            12:  * portions copyright 1991 by Insignia Solutions Ltd., used by permission.
        !            13:  *
        !            14:  * revision history:
        !            15:  *  24-Dec-1992 John Morgan:  written based (in part) on 
        !            16:  *                             serial driver support from Windows NT VDM.
        !            17:  *
        !            18:  */
        !            19: 
        !            20: 
        !            21: //
        !            22: //    useful utility macros
        !            23: //
        !            24: #include "util_def.h"
        !            25: 
        !            26: //
        !            27: //    standard library include files
        !            28: //
        !            29: #include <windows.h>
        !            30: 
        !            31: #include <stdio.h>
        !            32: #include <ctype.h>
        !            33: #include <sys/types.h>
        !            34: #include <string.h>
        !            35: 
        !            36: //
        !            37: //    COM_VDD specific include files
        !            38: //
        !            39: #include "com_vdd.h"
        !            40: #include "PC_def.h"
        !            41: #include "PC_com.h"
        !            42: #include "NT_com.h"
        !            43: #include "vddsvc.h"
        !            44: 
        !            45: /*
        !            46:  * =====================================================================
        !            47:  * Subsidiary functions - for interrupt emulation
        !            48:  * =====================================================================
        !            49:  */
        !            50: static void check_interrupt( UART_STATE *asp )
        !            51: {
        !            52:     /*
        !            53:      * Follow somewhat dubious advice on Page 1-188 of XT Tech Ref
        !            54:      * regarding the adapter card sending interrupts to the system.
        !            55:      * Apparently confirmed by the logic diagram.
        !            56:      */
        !            57:     if (asp->out2_state
        !            58:         && !asp->loopback_state
        !            59:         && (asp->data_available_interrupt_state
        !            60:             || asp->tx_holding_register_empty_interrupt_state
        !            61:             || asp->receiver_line_status_interrupt_state
        !            62:             || asp->modem_status_interrupt_state))
        !            63:     {
        !            64:         if (!asp->interrupt_line_state)
        !            65:         {
        !            66:             asp->interrupt_line_state = TRUE;
        !            67:             VDDSimulateInterrupt( 0, asp->hw_interrupt_priority, 1);
        !            68:         }
        !            69:     }     
        !            70:     else
        !            71:     {
        !            72:         asp->interrupt_line_state = FALSE;
        !            73:     }
        !            74: }
        !            75: 
        !            76: extern void raise_rls_interrupt( UART_STATE *asp )
        !            77: {
        !            78:     /*
        !            79:      * Check if receiver line status interrupt is enabled
        !            80:      */
        !            81:     if (asp->int_enable_reg.bits.rx_line)
        !            82:     {
        !            83:         asp->receiver_line_status_interrupt_state = TRUE;
        !            84:         check_interrupt(asp);
        !            85:     }
        !            86: }
        !            87: 
        !            88: extern void raise_rda_interrupt( UART_STATE *asp )
        !            89: {
        !            90:     /*
        !            91:      * Check if data available interrupt is enabled
        !            92:      */
        !            93:     if (asp->int_enable_reg.bits.data_available)
        !            94:     {
        !            95:         asp->data_available_interrupt_state = TRUE;
        !            96:         check_interrupt(asp);
        !            97:     }
        !            98: }
        !            99: 
        !           100: extern void raise_ms_interrupt( UART_STATE *asp )
        !           101: {
        !           102:     /*
        !           103:      * Check if modem status interrupt is enabled
        !           104:      */
        !           105:     if (asp->int_enable_reg.bits.modem_status)
        !           106:     {
        !           107:         asp->modem_status_interrupt_state = TRUE;
        !           108:         check_interrupt(asp);
        !           109:     }
        !           110:     asp->modem_status_changed = TRUE;
        !           111: }
        !           112: 
        !           113: extern void raise_thre_interrupt( UART_STATE *asp )
        !           114: {
        !           115:     /*
        !           116:      * Check if tx holding register empty interrupt is enabled
        !           117:      */
        !           118:     if (asp->int_enable_reg.bits.tx_holding)
        !           119:     {
        !           120:         asp->tx_holding_register_empty_interrupt_state = TRUE;
        !           121:         check_interrupt(asp);
        !           122:     }
        !           123: }
        !           124: 
        !           125: 
        !           126: /*
        !           127:  * =====================================================================
        !           128:  * Subsidiary functions - for data available
        !           129:  * =====================================================================
        !           130:  */
        !           131: 
        !           132: /*
        !           133:  * signal all characters transmitted!
        !           134:  */
        !           135: void clear_tbr_flag( UART_STATE *asp )
        !           136: {
        !           137:     asp->line_status_reg.bits.tx_shift_empty = 1;
        !           138: }
        !           139: 
        !           140: /*
        !           141:  * check for data available and line status changes
        !           142:  */
        !           143: static void check_data_available( tAdapter adapter )
        !           144: {
        !           145:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           146:     DWORD error;
        !           147:     
        !           148:     if (!asp->loopback_state)
        !           149:     {
        !           150:         if (!asp->line_status_reg.bits.data_ready)
        !           151:         {
        !           152:             if (!(asp->line_status_reg.bits.data_ready = host_com_read_rx( adapter, &asp->rx_buff_reg ))
        !           153:                 && asp->int_enable_reg.bits.data_available)
        !           154:             {
        !           155:                 host_com_rx_wait( adapter );
        !           156:             }
        !           157:         }
        !           158: 
        !           159:         if ((error = host_com_get_error( adapter )) != 0)
        !           160:         {
        !           161:             /*
        !           162:              * Set line status register and raise line status interrupt
        !           163:              */
        !           164:             if (error & (CE_OVERRUN | CE_RXOVER))
        !           165:                 asp->line_status_reg.bits.overrun_error = 1;
        !           166: 
        !           167:             if (error & CE_FRAME)
        !           168:                 asp->line_status_reg.bits.framing_error = 1;
        !           169: 
        !           170:             if (error & CE_RXPARITY)
        !           171:                 asp->line_status_reg.bits.parity_error = 1;
        !           172: 
        !           173:             if (error & CE_BREAK)
        !           174:                 asp->line_status_reg.bits.break_interrupt = 1;
        !           175: 
        !           176:             raise_rls_interrupt( asp );
        !           177:         }
        !           178:     }
        !           179: }
        !           180: 
        !           181: 
        !           182: /*
        !           183:  * flush all received input
        !           184:  */
        !           185: static void com_flush_input(tAdapter adapter)
        !           186: {
        !           187:     BYTE dummy;
        !           188:     
        !           189:     while (host_com_read_rx( adapter, &dummy ))
        !           190:         /* do nothing */;
        !           191: 
        !           192:     UART_ADAPTER(adapter).line_status_reg.bits.data_ready = FALSE;
        !           193: }
        !           194: 
        !           195: /*
        !           196:  * set the IIR for current interrupts pending
        !           197:  */
        !           198: static BYTE generate_iir( tAdapter adapter )
        !           199: {
        !           200:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           201: 
        !           202:     /*
        !           203:      * Set up interrupt identification register with highest priority
        !           204:      * pending interrupt.
        !           205:      */
        !           206: 
        !           207:     check_data_available( adapter );
        !           208: 
        !           209:     return 
        !           210:         (asp->receiver_line_status_interrupt_state) ?           UART_RLS_INT
        !           211:         : (asp->line_status_reg.bits.data_ready) ?              UART_RDA_INT
        !           212:           : (asp->tx_holding_register_empty_interrupt_state) ?  UART_THRE_INT
        !           213:             : (asp->modem_status_interrupt_state) ?             UART_MS_INT
        !           214:               :                                                 UART_NO_INT;
        !           215: }
        !           216: 
        !           217: 
        !           218: /*
        !           219:  * set modem status register to new status
        !           220:  */
        !           221: static void set_modem_status( tAdapter adapter, long modem_status )
        !           222: {
        !           223:     UART_STATE *asp = & UART_ADAPTER( adapter );
        !           224:     int cts_state, dsr_state, rlsd_state, ri_state;
        !           225: 
        !           226:     cts_state  = ((modem_status & HOST_MS_CTS)  != 0);
        !           227:     dsr_state  = ((modem_status & HOST_MS_DSR)  != 0);
        !           228:     rlsd_state = ((modem_status & HOST_MS_RLSD) != 0);
        !           229:     ri_state   = ((modem_status & HOST_MS_RI)   != 0);
        !           230: 
        !           231:     /*
        !           232:      * Establish CTS state
        !           233:      */
        !           234:     if (cts_state != asp->modem_status_reg.bits.CTS)
        !           235:     {
        !           236:         asp->modem_status_reg.bits.CTS = cts_state;
        !           237:         asp->modem_status_reg.bits.delta_CTS = TRUE;
        !           238:         raise_ms_interrupt(asp);
        !           239:     }
        !           240: 
        !           241:     /*
        !           242:      * Establish DSR state
        !           243:      */
        !           244:     if (dsr_state != asp->modem_status_reg.bits.DSR)
        !           245:     {
        !           246:         asp->modem_status_reg.bits.DSR = dsr_state;
        !           247:         asp->modem_status_reg.bits.delta_DSR = TRUE;
        !           248:         raise_ms_interrupt(asp);
        !           249:     }
        !           250: 
        !           251:     /*
        !           252:      * Establish RLSD state
        !           253:      */
        !           254:     if (rlsd_state != asp->modem_status_reg.bits.RLSD)
        !           255:     {
        !           256:         asp->modem_status_reg.bits.RLSD = rlsd_state;
        !           257:         asp->modem_status_reg.bits.delta_RLSD = TRUE;
        !           258:         raise_ms_interrupt(asp);
        !           259:     }
        !           260: 
        !           261:     /*
        !           262:      * Establish RI state
        !           263:      */
        !           264:     if (ri_state != asp->modem_status_reg.bits.RI)
        !           265:     {
        !           266:         if ((asp->modem_status_reg.bits.RI = ri_state) == FALSE)
        !           267:         {
        !           268:             asp->modem_status_reg.bits.TERI = TRUE;
        !           269:             raise_ms_interrupt(asp);
        !           270:         }
        !           271:     }
        !           272: }
        !           273: 
        !           274: /*
        !           275:  * One of the modem control input lines has changed state
        !           276:  */
        !           277: static void refresh_modem_status( tAdapter adapter )
        !           278: {
        !           279:     /*
        !           280:      * Update the modem status register after a change to one of the
        !           281:      * modem status input lines
        !           282:      */
        !           283:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           284: 
        !           285:     if (! UART_ADAPTER(adapter).loopback_state)
        !           286:     {
        !           287:         /* get current modem input state */
        !           288:         set_modem_status( adapter, host_com_ioctl( adapter, HOST_COM_MSTATUS, 0 ) );
        !           289:     }
        !           290: }
        !           291: 
        !           292: 
        !           293: /*
        !           294:  * =====================================================================
        !           295:  * Subsidiary functions - for setting comms parameters
        !           296:  * =====================================================================
        !           297:  */
        !           298: 
        !           299: static void set_baud_rate( tAdapter adapter )
        !           300: {
        !           301:     const long UART_bit_clock = 115200;
        !           302:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           303: 
        !           304:     if (UART_ADAPTER(adapter).divisor_latch.all != 0)
        !           305:     {
        !           306:         com_flush_input( adapter );
        !           307:         host_com_ioctl( adapter, 
        !           308:                         HOST_COM_BAUD, 
        !           309:                         UART_bit_clock / UART_ADAPTER(adapter).divisor_latch.all
        !           310:                       );
        !           311:     }
        !           312: }
        !           313: 
        !           314: static void set_break( tAdapter adapter )
        !           315: {
        !           316:     /*
        !           317:      * Process the set break control bit. Bit 6 of the Line Control
        !           318:      * Register.
        !           319:      */
        !           320:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           321: 
        !           322:     if (asp->line_control_reg.bits.set_break != asp->break_state )
        !           323:     {
        !           324:         asp->break_state = asp->line_control_reg.bits.set_break;
        !           325:         host_com_ioctl( adapter, HOST_COM_SBRK, 0 );
        !           326:     }
        !           327: }
        !           328: 
        !           329: static void set_line_control( tAdapter adapter )
        !           330: {
        !           331:     /*
        !           332:      * Set Number of data bits
        !           333:      *     Parity bits
        !           334:      *     Number of stop bits
        !           335:      */
        !           336:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           337:     int host_line_ctrl;
        !           338:     const int host_bits[4][2] =
        !           339:         { HOST_LC_DATA_5 | HOST_LC_STOP_1,
        !           340:           HOST_LC_DATA_5 | HOST_LC_STOP_15,
        !           341:           HOST_LC_DATA_6 | HOST_LC_STOP_1,
        !           342:           HOST_LC_DATA_6 | HOST_LC_STOP_2,
        !           343:           HOST_LC_DATA_7 | HOST_LC_STOP_1,
        !           344:           HOST_LC_DATA_7 | HOST_LC_STOP_2,
        !           345:           HOST_LC_DATA_8 | HOST_LC_STOP_1,
        !           346:           HOST_LC_DATA_8 | HOST_LC_STOP_2};
        !           347: 
        !           348:     host_line_ctrl =
        !           349: 
        !           350:     // the number of data bits
        !           351:         host_bits[asp->line_control_reg.bits.word_length]
        !           352: 
        !           353:     // and stop bits
        !           354:                     [asp->line_control_reg.bits.no_of_stop_bits]
        !           355: 
        !           356:     // and the parity settings
        !           357:         | ((asp->line_control_reg.bits.parity_enabled == UART_PARITY_OFF)
        !           358:             ? HOST_LC_PARITY_NONE
        !           359: 
        !           360:             : (asp->line_control_reg.bits.stick_parity == UART_PARITY_STICK)
        !           361:                 ? (asp->line_control_reg.bits.even_parity == UART_PARITY_ODD)
        !           362:                     ? HOST_LC_PARITY_MARK
        !           363: 
        !           364:                     : HOST_LC_PARITY_SPACE
        !           365: 
        !           366:                 : (asp->line_control_reg.bits.even_parity == UART_PARITY_ODD)
        !           367:                     ? HOST_LC_PARITY_ODD
        !           368: 
        !           369:                     : HOST_LC_PARITY_EVEN
        !           370:           );
        !           371: 
        !           372:     host_com_ioctl(adapter, HOST_COM_LINE_CTRL, host_line_ctrl);
        !           373: }
        !           374: 
        !           375: void set_modem_control( tAdapter adapter )
        !           376: {
        !           377:     UART_STATE *asp = & UART_ADAPTER( adapter );
        !           378: 
        !           379:     /*
        !           380:      * Process the loopback control bit
        !           381:      */
        !           382: 
        !           383:     if (asp->modem_control_reg.bits.loop != asp->loopback_state)
        !           384:     {
        !           385:         if (!(asp->loopback_state = asp->modem_control_reg.bits.loop))
        !           386:         {
        !           387:             /*
        !           388:              * Reset the modem status inputs according to the real
        !           389:              * modem status
        !           390:              */
        !           391:             refresh_modem_status( adapter );
        !           392:         }
        !           393:     }
        !           394: 
        !           395:     /*
        !           396:      * Modem control function depends on the loopback control bit
        !           397:      */
        !           398:     
        !           399:     if (asp->loopback_state)
        !           400:     {
        !           401:         set_modem_status( adapter, 
        !           402: 
        !           403:         // loop DTR back to DSR
        !           404:             (asp->modem_control_reg.bits.DTR && HOST_MS_DSR)
        !           405: 
        !           406:         // loop RTS back to CTS
        !           407:             | (asp->modem_control_reg.bits.RTS && HOST_MS_CTS)
        !           408:     
        !           409:         // loop OUT1 back to RI
        !           410:             | (asp->modem_control_reg.bits.OUT1 && HOST_MS_RI)
        !           411: 
        !           412:         // loop OUT2 back to RLSD
        !           413:             | (asp->modem_control_reg.bits.OUT2 && HOST_MS_RLSD) );
        !           414: 
        !           415:     }
        !           416:     else  // not in loopback state
        !           417:     {
        !           418:         int host_modem_control = 
        !           419:             (asp->modem_control_reg.bits.DTR ? HOST_MC_DTR : 0)
        !           420:             | (asp->modem_control_reg.bits.RTS ? HOST_MC_RTS : 0);
        !           421: 
        !           422:         /*
        !           423:          * In the real adapter, the OUT1 control bit is not connected
        !           424:          * so no real modem control change is required
        !           425:          */
        !           426: 
        !           427:         /*
        !           428:          * In the real adapter the OUT2 control bit is used to determine
        !           429:          * whether the communications card can send interrupts; so no
        !           430:          * real modem control change is required
        !           431:          */
        !           432:         asp->out2_state = asp->modem_control_reg.bits.OUT2;
        !           433: 
        !           434:         if (asp->modem_ctrl_state != host_modem_control)
        !           435:         {
        !           436:             asp->modem_ctrl_state = host_modem_control;
        !           437:             host_com_ioctl( adapter, HOST_COM_MODEM_CTRL, host_modem_control );
        !           438:         }
        !           439:     }
        !           440: }
        !           441: 
        !           442: void com_reset(tAdapter adapter)
        !           443: {
        !           444:     /*
        !           445:      * Set host devices to current state
        !           446:      */
        !           447:     set_baud_rate( adapter );
        !           448:     set_line_control( adapter );
        !           449:     set_break( adapter );
        !           450:     set_modem_control( adapter );
        !           451: }
        !           452: 
        !           453: static int port_start[4] = {PC_COM1_PORT_START,
        !           454:                             PC_COM2_PORT_START,
        !           455:                             PC_COM3_PORT_START,
        !           456:                             PC_COM4_PORT_START};
        !           457: static int port_end[4] = {PC_COM1_PORT_END,
        !           458:                           PC_COM2_PORT_END,
        !           459:                           PC_COM3_PORT_END,
        !           460:                           PC_COM4_PORT_END};
        !           461: static int int_pri[4] = {PC_COM1_INT,
        !           462:                          PC_COM2_INT,
        !           463:                          PC_COM3_INT,
        !           464:                          PC_COM4_INT};
        !           465: static int timeout[4] = {PC_COM1_TIMEOUT,
        !           466:                          PC_COM2_TIMEOUT,
        !           467:                          PC_COM3_TIMEOUT,
        !           468:                          PC_COM4_TIMEOUT};
        !           469: 
        !           470: void com_init( tAdapter adapter )
        !           471: {
        !           472:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           473: 
        !           474:     asp->had_first_read = FALSE;
        !           475:     asp->hw_interrupt_priority = int_pri[adapter];
        !           476: 
        !           477:     /*
        !           478:      * Set default state of all adapter registers
        !           479:      */
        !           480:     asp->int_enable_reg.all = 0;
        !           481: 
        !           482:     asp->line_control_reg.all = 0;
        !           483:     asp->line_control_reg.bits.word_length = 3;
        !           484: 
        !           485:     asp->line_status_reg.all = 0;
        !           486:     asp->line_status_reg.bits.tx_holding_empty = 1;
        !           487:     asp->line_status_reg.bits.tx_shift_empty = 1;
        !           488: 
        !           489:     asp->break_state = FALSE;
        !           490: 
        !           491:     /*
        !           492:      * set up modem control reg so set_modem_control 
        !           493:      * will set host adapter to the reset state
        !           494:      */
        !           495:     asp->modem_control_reg.all = 0;
        !           496: 
        !           497:     asp->modem_control_reg.bits.DTR = TRUE;
        !           498:     asp->modem_control_reg.bits.RTS = TRUE;
        !           499:     asp->modem_control_reg.bits.OUT1 = TRUE;
        !           500:     asp->modem_control_reg.bits.OUT2 = TRUE;
        !           501: 
        !           502:     asp->modem_ctrl_state = 0;      // different from DTR & RTS
        !           503:     asp->loopback_state = FALSE;
        !           504:     asp->divisor_latch_state = asp->line_control_reg.bits.DLAB;
        !           505: 
        !           506:     asp->modem_status_reg.all = 0;
        !           507:     asp->modem_status_changed = TRUE;
        !           508: 
        !           509:     /*
        !           510:      * Set up default state of our state variables
        !           511:      */
        !           512: 
        !           513:     asp->receiver_line_status_interrupt_state = FALSE;
        !           514:     asp->data_available_interrupt_state = FALSE;
        !           515:     asp->tx_holding_register_empty_interrupt_state = FALSE;
        !           516:     asp->modem_status_interrupt_state = FALSE;
        !           517: 
        !           518:     check_interrupt( asp );         /* sets interrupt line state */
        !           519: 
        !           520:     return;
        !           521: }
        !           522: 
        !           523: void com_close(tAdapter adapter)
        !           524: {
        !           525: }
        !           526: 
        !           527: 
        !           528: /*
        !           529:  * =====================================================================
        !           530:  * The Adaptor functions
        !           531:  * =====================================================================
        !           532:  */
        !           533: 
        !           534: static void inb_RBR( tAdapter adapter, BYTE *value )
        !           535: {
        !           536:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           537: 
        !           538:     if (asp->divisor_latch_state)
        !           539:         *value = asp->divisor_latch.byte.LSB;
        !           540:     else
        !           541:     {
        !           542:         host_com_lock(adapter);
        !           543: 
        !           544:         //
        !           545:         // Read of rx buffer
        !           546:         //
        !           547:         check_data_available( adapter );               // get char if available
        !           548: 
        !           549:         *value = asp->rx_buff_reg;
        !           550:         asp->line_status_reg.bits.data_ready = FALSE;  // signal character read
        !           551: 
        !           552:         check_data_available( adapter );               // check next char
        !           553:         
        !           554:         asp->data_available_interrupt_state = 
        !           555:             (asp->int_enable_reg.bits.data_available
        !           556:              && asp->line_status_reg.bits.data_ready);
        !           557:         check_interrupt(asp);                          // set interrupt line
        !           558: 
        !           559:         host_com_unlock(adapter);
        !           560:     }
        !           561: }
        !           562: 
        !           563: static void inb_IER( tAdapter adapter, BYTE *value )
        !           564: {
        !           565:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           566: 
        !           567:     if (asp->divisor_latch_state)
        !           568:         *value = asp->divisor_latch.byte.MSB;
        !           569:     else
        !           570:         *value = asp->int_enable_reg.all;
        !           571: }
        !           572: 
        !           573: static void inb_IIR( tAdapter adapter, BYTE *value )
        !           574: {
        !           575:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           576: 
        !           577:     host_com_lock( adapter );
        !           578: 
        !           579:     if ((*value = generate_iir( adapter )) == UART_THRE_INT)
        !           580:     {
        !           581:         asp->tx_holding_register_empty_interrupt_state = FALSE;
        !           582:         check_interrupt( asp ); 
        !           583:     }
        !           584:  
        !           585:     host_com_unlock(adapter);
        !           586: }
        !           587: 
        !           588: static void inb_LCR( tAdapter adapter, BYTE *value )
        !           589: {
        !           590:     *value = UART_ADAPTER(adapter).line_control_reg.all;
        !           591: }
        !           592: 
        !           593: static void inb_MCR( tAdapter adapter, BYTE *value )
        !           594: {
        !           595:     *value = UART_ADAPTER(adapter).modem_control_reg.all;
        !           596: }
        !           597: 
        !           598: static void inb_LSR( tAdapter adapter, BYTE *value )
        !           599: {
        !           600:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           601:     host_com_lock(adapter);
        !           602:  
        !           603:     *value = asp->line_status_reg.all;
        !           604: 
        !           605:     asp->line_status_reg.bits.overrun_error = 0;
        !           606:     asp->line_status_reg.bits.parity_error = 0;
        !           607:     asp->line_status_reg.bits.framing_error = 0;
        !           608:     asp->line_status_reg.bits.break_interrupt = 0;
        !           609:     asp->receiver_line_status_interrupt_state = FALSE;
        !           610:     check_interrupt(asp);
        !           611: 
        !           612:     host_com_unlock(adapter);
        !           613: }
        !           614: 
        !           615: static void inb_MSR( tAdapter adapter, BYTE *value )
        !           616: {
        !           617:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           618: 
        !           619:     if (!asp->modem_status_changed && !asp->loopback_state)
        !           620:     {
        !           621:         *value = asp->last_modem_status_value.all;
        !           622:     }
        !           623:     else
        !           624:     {
        !           625:         host_com_lock(adapter);
        !           626: 
        !           627:         if (asp->loopback_state)
        !           628:         {
        !           629:             *value = asp->modem_status_reg.all;
        !           630:             asp->modem_status_changed = TRUE;
        !           631:         }
        !           632:         else
        !           633:         {
        !           634:             refresh_modem_status( adapter );
        !           635:             *value = asp->modem_status_reg.all;
        !           636:             asp->modem_status_changed = FALSE;
        !           637:         }
        !           638: 
        !           639:         asp->modem_status_reg.bits.delta_CTS = 0;
        !           640:         asp->modem_status_reg.bits.delta_DSR = 0;
        !           641:         asp->modem_status_reg.bits.delta_RLSD = 0;
        !           642:         asp->modem_status_reg.bits.TERI = 0;
        !           643:         asp->modem_status_interrupt_state = FALSE;
        !           644:         check_interrupt(asp);
        !           645:         asp->last_modem_status_value.all = asp->modem_status_reg.all;
        !           646: 
        !           647:         host_com_unlock(adapter);
        !           648:     }
        !           649: }
        !           650: 
        !           651: static void inb_SCR( tAdapter adapter, BYTE *value )
        !           652: {
        !           653:     *value = UART_ADAPTER(adapter).scratch; // Just read the value stored.
        !           654: }
        !           655: 
        !           656: void com_inb( WORD port, BYTE *value )
        !           657: {
        !           658:     void (*(inb_func[]))( int, BYTE * ) =
        !           659:     {
        !           660:         inb_RBR,
        !           661:         inb_IER,
        !           662:         inb_IIR,
        !           663:         inb_LCR,
        !           664:         inb_MCR,
        !           665:         inb_LSR,
        !           666:         inb_MSR,
        !           667:         inb_SCR
        !           668:     };
        !           669:     tAdapter adapter = adapter_for_port(port);
        !           670: 
        !           671:     if (adapter < NUM_SERIAL_PORTS)
        !           672:         inb_func[port & 0x7] (adapter, value);
        !           673:     else
        !           674:         *value = 0xFF;
        !           675: }
        !           676: 
        !           677: 
        !           678: static void outb_THR( tAdapter adapter, BYTE value )
        !           679: {
        !           680:     const BYTE selectBits[4] = { 0x1f, 0x3f, 0x7f, 0xff } ;
        !           681:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           682: 
        !           683:     host_com_lock(adapter);
        !           684: 
        !           685:     if (asp->divisor_latch_state)
        !           686:     {
        !           687:         if (asp->divisor_latch.byte.LSB != value)
        !           688:         {
        !           689:             asp->divisor_latch.byte.LSB = value;
        !           690:             asp->baud_rate_changed = TRUE;
        !           691:         }
        !           692:     }
        !           693:     else
        !           694:     {
        !           695:         /*
        !           696:          * Write char to tx buffer
        !           697:          */
        !           698:         if (!asp->loopback_state)
        !           699:         {
        !           700:             asp->line_status_reg.bits.tx_shift_empty = 0;
        !           701:             host_com_write_tx( adapter, value );
        !           702:         }
        !           703:         else
        !           704:         {
        !           705:             /* Loopback case requires masking off */
        !           706:             /* of bits based upon word length.    */
        !           707:             asp->rx_buff_reg = value 
        !           708:                              & selectBits[ asp->line_control_reg.bits.word_length ];
        !           709: 
        !           710:             /*
        !           711:              * Check for data overrun and set up correct interrupt
        !           712:              */
        !           713:             if ( asp->line_status_reg.bits.data_ready)
        !           714:             {
        !           715:                 asp->line_status_reg.bits.overrun_error = TRUE;
        !           716:                 raise_rls_interrupt(asp);
        !           717:             }
        !           718:             else
        !           719:             {
        !           720:                 asp->line_status_reg.bits.data_ready = TRUE;
        !           721:                 raise_rda_interrupt(asp);
        !           722:             }
        !           723:             asp->line_status_reg.bits.tx_shift_empty = 1;
        !           724:         }
        !           725: 
        !           726:         // holding register permanently empty!!!
        !           727:         asp->line_status_reg.bits.tx_holding_empty = 1;
        !           728:         raise_thre_interrupt( asp );
        !           729:     }
        !           730: 
        !           731:     host_com_unlock(adapter);
        !           732: }
        !           733: 
        !           734: static void outb_IER( tAdapter adapter, BYTE value )
        !           735: {
        !           736:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           737:     host_com_lock(adapter);
        !           738: 
        !           739:     if (asp->divisor_latch_state)
        !           740:     {
        !           741:         if (asp->divisor_latch.byte.MSB != value)
        !           742:         {
        !           743:             asp->divisor_latch.byte.MSB = value;
        !           744:             asp->baud_rate_changed = TRUE;
        !           745:         }
        !           746:     }
        !           747:     else
        !           748:     {
        !           749:         int org_da = asp->int_enable_reg.bits.data_available;
        !           750: 
        !           751:         asp->int_enable_reg.all = value & 0xf;
        !           752: 
        !           753:         //
        !           754:         // Kill off any pending interrupts for those items
        !           755:         // which are set now as disabled
        !           756:         //
        !           757:         if (!asp->int_enable_reg.bits.data_available)
        !           758:             asp->data_available_interrupt_state = FALSE;
        !           759: 
        !           760:         if (!asp->int_enable_reg.bits.tx_holding)
        !           761:             asp->tx_holding_register_empty_interrupt_state = FALSE;
        !           762: 
        !           763:         if (!asp->int_enable_reg.bits.rx_line)
        !           764:             asp->receiver_line_status_interrupt_state = FALSE;
        !           765: 
        !           766:         if (!asp->int_enable_reg.bits.modem_status)
        !           767:             asp->modem_status_interrupt_state = FALSE;
        !           768: 
        !           769:         //
        !           770:         // Check for immediately actionable interrupts
        !           771:         //
        !           772:         check_data_available( adapter );
        !           773:         if ( asp->line_status_reg.bits.data_ready == 1 )
        !           774:             raise_rda_interrupt( asp );
        !           775:         if ( asp->line_status_reg.bits.tx_holding_empty == 1 )
        !           776:             raise_thre_interrupt( asp );
        !           777: 
        !           778:         check_interrupt(asp);       // lower int line if no outstanding interrupts
        !           779: 
        !           780:     }
        !           781: 
        !           782:     host_com_unlock(adapter);
        !           783: }
        !           784: 
        !           785: static void outb_IIR( tAdapter adapter, BYTE value )
        !           786: {
        !           787:     //
        !           788:     // Essentially a READ ONLY register
        !           789:     //
        !           790: }
        !           791: 
        !           792: static void outb_LCR( tAdapter adapter, BYTE value )
        !           793: {
        !           794:     const LINE_CONTROL_REG LCRFlushMask = 
        !           795:     {
        !           796:         (unsigned) ~0,    // word_length:2;
        !           797:         (unsigned)  0,    // no_of_stop_bits:1;
        !           798:         (unsigned) ~0,    // parity_enabled:1;
        !           799:         (unsigned) ~0,    // even_parity:1;
        !           800:         (unsigned) ~0,    // stick_parity:1;
        !           801:         (unsigned)  0,    // set_break:1;
        !           802:         (unsigned)  0     // DLAB:1;
        !           803:     };
        !           804:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           805: 
        !           806:     host_com_lock(adapter);
        !           807:     if (((value ^ asp->line_control_reg.all) & LCRFlushMask.all) != 0)
        !           808:         com_flush_input(adapter);
        !           809: 
        !           810:     if (asp->line_control_reg.all != value)
        !           811:     {
        !           812:         asp->line_control_reg.all = value;
        !           813:         set_line_control( adapter );
        !           814:     }
        !           815: 
        !           816:     if (asp->divisor_latch_state != asp->line_control_reg.bits.DLAB)
        !           817:     {
        !           818:         asp->divisor_latch_state = asp->line_control_reg.bits.DLAB;
        !           819:         if (asp->divisor_latch_state)
        !           820:             asp->baud_rate_changed = FALSE;
        !           821:         else
        !           822:         {
        !           823:             if (asp -> baud_rate_changed)
        !           824:             {
        !           825:                 set_baud_rate(adapter);
        !           826:             }
        !           827:         }
        !           828:     }
        !           829: 
        !           830:     set_break(adapter);
        !           831: 
        !           832:     host_com_unlock(adapter);
        !           833: }
        !           834: 
        !           835: static void outb_MCR( tAdapter adapter, BYTE value )
        !           836: {
        !           837:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           838:     host_com_lock(adapter);
        !           839: 
        !           840:     // Optimisation - DOS keeps re-writing this register
        !           841:     if ( asp->modem_control_reg.all != value )
        !           842:     {
        !           843:         asp->modem_control_reg.all = value;
        !           844:         asp->modem_control_reg.bits.pad = 0;
        !           845: 
        !           846:         set_modem_control(adapter);
        !           847:     }
        !           848: 
        !           849:     host_com_unlock(adapter);
        !           850: }
        !           851: 
        !           852: static void outb_LSR( tAdapter adapter, BYTE value )
        !           853: {
        !           854:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           855:     int temp;
        !           856: 
        !           857:     host_com_lock(adapter);
        !           858: 
        !           859:     temp = asp->line_status_reg.bits.tx_shift_empty;   /* READ ONLY */
        !           860:     asp->line_status_reg.all = value;
        !           861:     asp->line_status_reg.bits.tx_shift_empty = temp;
        !           862: 
        !           863:     host_com_unlock(adapter);
        !           864: }
        !           865: 
        !           866: static void outb_MSR( tAdapter adapter, BYTE value )
        !           867: {
        !           868:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           869:     host_com_lock(adapter);
        !           870: 
        !           871:     //
        !           872:     // Essentially a READ ONLY register, except that DR-DOS
        !           873:     // writes to this reg after setting int on MSR change and
        !           874:     // expects to get an interrupt back!!! So we will oblige.
        !           875:     // Writing to this reg only seems to affect the delta bits
        !           876:     // (bits 0-3) of the reg.
        !           877:     //
        !           878:     if (((value ^ asp->modem_status_reg.all) & 0xf) != 0)
        !           879:     {
        !           880:         asp->modem_status_reg.all &= 0xf0;
        !           881:         asp->modem_status_reg.all |= value & 0xf;
        !           882:         if (!asp->loopback_state)
        !           883:             raise_ms_interrupt(asp);
        !           884:     }
        !           885: 
        !           886:     host_com_unlock(adapter);
        !           887: }
        !           888: 
        !           889: static void outb_SCR( tAdapter adapter, BYTE value )
        !           890: {
        !           891:     UART_STATE *asp = & UART_ADAPTER(adapter);
        !           892:     asp->scratch = value;           // Scratch register - just store the value.
        !           893: }
        !           894: 
        !           895: void com_outb(WORD port, BYTE value)
        !           896: {
        !           897:     void (*(outb_func[]))(int, BYTE) =
        !           898:     {
        !           899:         outb_THR,
        !           900:         outb_IER,
        !           901:         outb_IIR,
        !           902:         outb_LCR,
        !           903:         outb_MCR,
        !           904:         outb_LSR,
        !           905:         outb_MSR,
        !           906:         outb_SCR
        !           907:     };
        !           908:     tAdapter adapter = adapter_for_port(port);
        !           909: 
        !           910:     if (adapter < NUM_SERIAL_PORTS)
        !           911:     {
        !           912:         outb_func[port & 0x7] (adapter, value);
        !           913:     }
        !           914: }
        !           915: 
        !           916: 
        !           917: /********************************************************/

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.