Annotation of quake1/net_comx.c, revision 1.1.1.3

1.1       root        1: // net_comx.c
                      2: 
                      3: #include <dos.h>
                      4: #include <dpmi.h>
                      5: 
                      6: #define NUM_COM_PORTS  2
                      7: 
                      8: #define ERR_TTY_LINE_STATUS            -1
                      9: #define ERR_TTY_MODEM_STATUS   -2
                     10: #define ERR_TTY_NODATA                 -3
                     11: 
                     12: #define QUEUESIZE      8192
                     13: #define QUEUEMASK      (QUEUESIZE - 1)
                     14: 
                     15: typedef struct
                     16: {
                     17:        volatile int  head;
                     18:        volatile int  tail;
                     19:        volatile byte data[QUEUESIZE];
                     20: } queue;
                     21: 
                     22: #define FULL(q)                        (q.head == ((q.tail-1) & QUEUEMASK))
                     23: #define EMPTY(q)               (q.tail == q.head)
                     24: #define ENQUEUE(q,b)   (q.data[q.head] = b, q.head = (q.head + 1) & QUEUEMASK)
                     25: #define DEQUEUE(q,b)   (b = q.data[q.tail], q.tail = (q.tail + 1) & QUEUEMASK)
                     26: 
                     27: extern cvar_t  config_com_port;
                     28: extern cvar_t  config_com_irq;
                     29: extern cvar_t  config_com_baud;
                     30: extern cvar_t  config_com_modem;
                     31: extern cvar_t  config_modem_dialtype;
                     32: extern cvar_t  config_modem_clear;
                     33: extern cvar_t  config_modem_init;
                     34: extern cvar_t  config_modem_hangup;
                     35: 
1.1.1.3 ! root       36: extern int m_return_state;
        !            37: extern int m_state;
        !            38: extern qboolean m_return_onerror;
        !            39: extern char m_return_reason[32];
        !            40: 
1.1       root       41: // 8250, 16550 definitions
                     42: #define TRANSMIT_HOLDING_REGISTER            0x00
                     43: #define RECEIVE_BUFFER_REGISTER              0x00
                     44: #define INTERRUPT_ENABLE_REGISTER            0x01
                     45: #define   IER_RX_DATA_READY                  0x01
                     46: #define   IER_TX_HOLDING_REGISTER_EMPTY      0x02
                     47: #define   IER_LINE_STATUS                    0x04
                     48: #define   IER_MODEM_STATUS                   0x08
                     49: #define INTERRUPT_ID_REGISTER                0x02
                     50: #define   IIR_MODEM_STATUS_INTERRUPT         0x00
                     51: #define   IIR_TX_HOLDING_REGISTER_INTERRUPT  0x02
                     52: #define   IIR_RX_DATA_READY_INTERRUPT        0x04
                     53: #define   IIR_LINE_STATUS_INTERRUPT          0x06
                     54: #define   IIR_FIFO_TIMEOUT                   0x0c
                     55: #define   IIR_FIFO_ENABLED                   0xc0
                     56: #define FIFO_CONTROL_REGISTER                0x02
                     57: #define   FCR_FIFO_ENABLE                    0x01
                     58: #define   FCR_RCVR_FIFO_RESET                0x02
                     59: #define   FCR_XMIT_FIFO_RESET                0x04
                     60: #define   FCR_TRIGGER_01                     0x00
                     61: #define   FCR_TRIGGER_04                     0x40
                     62: #define   FCR_TRIGGER_08                     0x80
                     63: #define   FCR_TRIGGER_16                     0xc0
                     64: #define LINE_CONTROL_REGISTER                0x03
                     65: #define   LCR_DATA_BITS_5                    0x00
                     66: #define   LCR_DATA_BITS_6                    0x01
                     67: #define   LCR_DATA_BITS_7                    0x02
                     68: #define   LCR_DATA_BITS_8                    0x03
                     69: #define   LCR_STOP_BITS_1                    0x00
                     70: #define   LCR_STOP_BITS_2                    0x04
                     71: #define   LCR_PARITY_NONE                    0x00
                     72: #define   LCR_PARITY_ODD                     0x08
                     73: #define   LCR_PARITY_EVEN                    0x18
                     74: #define   LCR_PARITY_MARK                    0x28
                     75: #define   LCR_PARITY_SPACE                   0x38
                     76: #define   LCR_SET_BREAK                      0x40
                     77: #define   LCR_DLAB                           0x80
                     78: #define MODEM_CONTROL_REGISTER               0x04
                     79: #define   MCR_DTR                            0x01
                     80: #define   MCR_RTS                            0x02
                     81: #define   MCR_OUT1                           0x04
                     82: #define   MCR_OUT2                           0x08
                     83: #define   MCR_LOOPBACK                       0x10
                     84: #define LINE_STATUS_REGISTER                 0x05
                     85: #define   LSR_DATA_READY                     0x01
                     86: #define   LSR_OVERRUN_ERROR                  0x02
                     87: #define   LSR_PARITY_ERROR                   0x04
                     88: #define   LSR_FRAMING_ERROR                  0x08
                     89: #define   LSR_BREAK_DETECT                   0x10
                     90: #define   LSR_TRANSMITTER_BUFFER_EMPTY       0x20
                     91: #define   LSR_TRANSMITTER_EMPTY              0x40
                     92: #define   LSR_FIFO_DIRTY                     0x80
                     93: #define MODEM_STATUS_REGISTER                0x06
                     94: #define   MSR_DELTA_CTS                      0x01
                     95: #define   MSR_DELTA_DSR                      0x02
                     96: #define   MSR_DELTA_RI                       0x04
                     97: #define   MSR_DELTA_CD                       0x08
                     98: #define   MSR_CTS                            0x10
                     99: #define   MSR_DSR                            0x20
                    100: #define   MSR_RI                             0x40
                    101: #define   MSR_CD                             0x80
                    102: #define DIVISOR_LATCH_LOW                    0x00
                    103: #define DIVISOR_LATCH_HIGH                   0x01
                    104: 
                    105: #define MODEM_STATUS_MASK      (MSR_CTS | MSR_DSR | MSR_CD)
                    106: 
                    107: #define UART_AUTO      0
                    108: #define UART_8250      1
                    109: #define UART_16550     2
                    110: 
                    111: static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
                    112: static int ISA_IRQs[]  = {4,3,4,3};
                    113: 
                    114: typedef struct ComPort_s
                    115: {
                    116:        struct ComPort_s                *next;
                    117:        _go32_dpmi_seginfo              protectedModeInfo;
                    118:        _go32_dpmi_seginfo              protectedModeSaveInfo;
                    119:        int                                             uart;
                    120:        volatile byte                   modemStatus;
                    121:        byte                                    modemStatusIgnore;
                    122:        byte                                    lineStatus;
                    123:        byte                                    bufferUsed;
                    124:        qboolean                                enabled;
                    125:        volatile qboolean               statusUpdated;
                    126:        qboolean                                useModem;
                    127:        qboolean                                modemInitialized;
                    128:        qboolean                                modemRang;
                    129:        qboolean                                modemConnected;
                    130:        queue                                   inputQueue;
                    131:        queue                                   outputQueue;
                    132:        char                                    clear[16];
                    133:        char                                    startup[32];
                    134:        char                                    shutdown[16];
                    135:        char                                    buffer[128];
                    136:        PollProcedure                   poll;
                    137:        double                                  timestamp;
                    138:        byte                                    uartType;
                    139:        byte                                    irq;
                    140:        byte                                    baudBits;
                    141:        byte                                    lineControl;
                    142:        byte                                    portNumber;
                    143:        char                                    dialType;
                    144:        char                                    name[4];
                    145: } ComPort;
                    146: 
                    147: ComPort *portList = NULL;
                    148: ComPort *handleToPort [NUM_COM_PORTS];
                    149: 
                    150: static int Modem_Command(ComPort *p, char *commandString);
                    151: static char *Modem_Response(ComPort *p);
                    152: static void Modem_Hangup(ComPort *p);
                    153: 
                    154: int TTY_Init(void);
                    155: void TTY_Shutdown(void);
                    156: int TTY_Open(int serialPortNumber);
                    157: void TTY_Close(int handle);
                    158: int TTY_ReadByte(int handle);
                    159: int TTY_WriteByte(int handle, byte data);
                    160: void TTY_Flush(int handle);
                    161: int TTY_Connect(int handle, char *host);
                    162: void TTY_Disconnect(int handle);
                    163: qboolean TTY_CheckForConnection(int handle);
                    164: qboolean TTY_IsEnabled(int serialPortNumber);
                    165: qboolean TTY_IsModem(int serialPortNumber);
                    166: qboolean TTY_OutputQueueIsEmpty(int handle);
                    167: 
                    168: static void ISR_8250 (ComPort *p)
                    169: {
                    170:        byte    source = 0;
                    171:        byte    b;
                    172: 
                    173:        disable();
                    174: 
                    175:        while((source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07) != 1)
                    176:        {
                    177:                switch (source)
                    178:                {
                    179:                        case IIR_RX_DATA_READY_INTERRUPT:
                    180:                                b = inportb (p->uart + RECEIVE_BUFFER_REGISTER);
                    181:                                if (! FULL(p->inputQueue))
                    182:                                {
                    183:                                        ENQUEUE (p->inputQueue, b);
                    184:                                }
                    185:                                else
                    186:                                {
                    187:                                        p->lineStatus |= LSR_OVERRUN_ERROR;
                    188:                                        p->statusUpdated = true;
                    189:                                }
                    190:                                break;
                    191: 
                    192:                        case IIR_TX_HOLDING_REGISTER_INTERRUPT:
                    193:                                if (! EMPTY(p->outputQueue))
                    194:                                {
                    195:                                        DEQUEUE (p->outputQueue, b);
                    196:                                        outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b);
                    197:                                }
                    198:                                break;
                    199: 
                    200:                        case IIR_MODEM_STATUS_INTERRUPT:
                    201:                                p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                    202:                                p->statusUpdated = true;
                    203:                                break;
                    204: 
                    205:                        case IIR_LINE_STATUS_INTERRUPT:
                    206:                                p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER);
                    207:                                p->statusUpdated = true;
                    208:                                break;
                    209:                }
                    210:                source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07;
                    211:        }
                    212:        outportb (0x20, 0x20);
                    213: }
                    214: 
                    215: static void COM1_ISR_8250 (void)
                    216: {
                    217:        ISR_8250 (handleToPort[0]);
                    218: }
                    219: 
                    220: static void COM2_ISR_8250 (void)
                    221: {
                    222:        ISR_8250 (handleToPort[1]);
                    223: }
                    224: 
                    225: 
                    226: 
                    227: static void ISR_16550 (ComPort *p)
                    228: {
                    229:        int             count;
                    230:        byte    source;
                    231:        byte    b;
                    232: 
                    233:        disable();
                    234:        while((source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07) != 1)
                    235:        {
                    236:                switch (source)
                    237:                {
                    238:                        case IIR_RX_DATA_READY_INTERRUPT:
                    239:                                do
                    240:                                {
                    241:                                        b = inportb (p->uart + RECEIVE_BUFFER_REGISTER);
                    242:                                        if (!FULL(p->inputQueue))
                    243:                                        {
                    244:                                                ENQUEUE (p->inputQueue, b);
                    245:                                        }
                    246:                                        else
                    247:                                        {
                    248:                                                p->lineStatus |= LSR_OVERRUN_ERROR;
                    249:                                                p->statusUpdated = true;
                    250:                                        }
                    251:                                } while (inportb (p->uart + LINE_STATUS_REGISTER) & LSR_DATA_READY);
                    252:                                break;
                    253: 
                    254:                        case IIR_TX_HOLDING_REGISTER_INTERRUPT:
                    255:                                count = 16;
                    256:                                while ((! EMPTY(p->outputQueue)) && count--)
                    257:                                {
                    258:                                        DEQUEUE (p->outputQueue, b);
                    259:                                        outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b);
                    260:                                }
                    261:                                break;
                    262: 
                    263:                        case IIR_MODEM_STATUS_INTERRUPT:
                    264:                                p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                    265:                                p->statusUpdated = true;
                    266:                                break;
                    267: 
                    268:                        case IIR_LINE_STATUS_INTERRUPT:
                    269:                                p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER);
                    270:                                p->statusUpdated = true;
                    271:                                break;
                    272:                }
                    273:                source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07;
                    274:        }
                    275: 
                    276:        // check for lost IIR_TX_HOLDING_REGISTER_INTERRUPT on 16550a!
                    277:        if (inportb (p->uart + LINE_STATUS_REGISTER ) & LSR_TRANSMITTER_EMPTY)
                    278:        {
                    279:                count = 16;
                    280:                while ((! EMPTY(p->outputQueue)) && count--)
                    281:                {
                    282:                        DEQUEUE (p->outputQueue, b);
                    283:                        outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b);
                    284:                }
                    285:        }
                    286: 
                    287:        outportb (0x20, 0x20);
                    288: }
                    289: 
                    290: static void COM1_ISR_16550 (void)
                    291: {
                    292:        ISR_16550 (handleToPort[0]);
                    293: }
                    294: 
                    295: static void COM2_ISR_16550 (void)
                    296: {
                    297:        ISR_16550 (handleToPort[1]);
                    298: }
                    299: 
                    300: 
                    301: void TTY_GetComPortConfig (int portNumber, int *port, int *irq, int *baud, qboolean *useModem)
                    302: {
                    303:        ComPort *p;
                    304: 
                    305:        p = handleToPort[portNumber];
                    306:        *port = p->uart;
                    307:        *irq = p->irq;
                    308:        *baud = 115200 / p->baudBits;
                    309:        *useModem = p->useModem;
                    310: }
                    311: 
                    312: void TTY_SetComPortConfig (int portNumber, int port, int irq, int baud, qboolean useModem)
                    313: {
                    314:        ComPort *p;
                    315:        float   temp;
                    316: 
                    317:        if (useModem)
                    318:        {
                    319:                if (baud == 14400)
                    320:                        baud = 19200;
                    321:                if (baud == 28800)
                    322:                        baud = 38400;
                    323:        }
                    324: 
                    325:        p = handleToPort[portNumber];
                    326:        p->uart = port;
                    327:        p->irq = irq;
                    328:        p->baudBits = 115200 / baud;
                    329:        p->useModem = useModem;
                    330: 
                    331:        if (useModem)
                    332:                temp = 1.0;
                    333:        else
                    334:                temp = 0.0;
                    335: 
                    336:        Cvar_SetValue ("_config_com_port", (float)port);
                    337:        Cvar_SetValue ("_config_com_irq", (float)irq);
                    338:        Cvar_SetValue ("_config_com_baud", (float)baud);
                    339:        Cvar_SetValue ("_config_com_modem", temp);
                    340: }
                    341: 
                    342: void TTY_GetModemConfig (int portNumber, char *dialType, char *clear, char *init, char *hangup)
                    343: {
                    344:        ComPort *p;
                    345: 
                    346:        p = handleToPort[portNumber];
                    347:        *dialType = p->dialType;
                    348:        Q_strcpy(clear, p->clear);
                    349:        Q_strcpy(init, p->startup);
                    350:        Q_strcpy(hangup, p->shutdown);
                    351: }
                    352: 
                    353: void TTY_SetModemConfig (int portNumber, char *dialType, char *clear, char *init, char *hangup)
                    354: {
                    355:        ComPort *p;
                    356: 
                    357:        p = handleToPort[portNumber];
                    358:        p->dialType = dialType[0];
                    359:        Q_strcpy(p->clear, clear);
                    360:        Q_strcpy(p->startup, init);
                    361:        Q_strcpy(p->shutdown, hangup);
                    362: 
                    363:        p->modemInitialized = false;
                    364: 
                    365:        Cvar_Set ("_config_modem_dialtype", dialType);
                    366:        Cvar_Set ("_config_modem_clear", clear);
                    367:        Cvar_Set ("_config_modem_init", init);
                    368:        Cvar_Set ("_config_modem_hangup", hangup);
                    369: }
                    370: 
                    371: 
                    372: static void ResetComPortConfig (ComPort *p)
                    373: {
                    374:        p->useModem = false;
                    375:        p->uartType = UART_AUTO;
                    376:        p->uart = ISA_uarts[p->portNumber];
                    377:        p->irq = ISA_IRQs[p->portNumber];
                    378:        p->modemStatusIgnore = MSR_CD | MSR_CTS | MSR_DSR;
                    379:        p->baudBits = 115200 / 57600;
                    380:        p->lineControl = LCR_DATA_BITS_8 | LCR_STOP_BITS_1 | LCR_PARITY_NONE;
1.1.1.3 ! root      381:        Q_strcpy(p->clear, "ATZ");
        !           382:        Q_strcpy(p->startup, "");
        !           383:        Q_strcpy(p->shutdown, "AT H");
1.1       root      384:        p->modemRang = false;
                    385:        p->modemConnected = false;
                    386:        p->statusUpdated = false;
                    387:        p->outputQueue.head = p->outputQueue.tail = 0;
                    388:        p->inputQueue.head = p->inputQueue.tail = 0;
                    389: }
                    390: 
                    391: 
                    392: static void ComPort_Enable(ComPort *p)
                    393: {
                    394:        void    (*isr)(void);
                    395:        int             n;
                    396:        byte    b;
                    397: 
                    398:        if (p->enabled)
                    399:        {
                    400:                Con_Printf("Already enabled\n");
                    401:                return;
                    402:        }
                    403: 
                    404:        // disable all UART interrupts
                    405:        outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0);
                    406: 
                    407:        // clear out any buffered uncoming data
                    408:        while((inportb (p->uart + LINE_STATUS_REGISTER)) & LSR_DATA_READY)
                    409:                inportb (p->uart + RECEIVE_BUFFER_REGISTER);
                    410: 
                    411:        // get the current line and modem status
                    412:        p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                    413:        p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER);
                    414: 
                    415:        // clear any UART interrupts
                    416:        do
                    417:        {
                    418:                n = inportb (p->uart + INTERRUPT_ID_REGISTER) & 7;
                    419:                if (n == IIR_RX_DATA_READY_INTERRUPT)
                    420:                        inportb (p->uart + RECEIVE_BUFFER_REGISTER);
                    421:        } while (!(n & 1));
                    422: 
                    423:        if (p->uartType == UART_AUTO)
                    424:        {
                    425:                outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE);
                    426:                b = inportb (p->uart + INTERRUPT_ID_REGISTER);
                    427:                if ((b & IIR_FIFO_ENABLED) == IIR_FIFO_ENABLED)
                    428:                        p->uartType = UART_16550;
                    429:                else
                    430:                        p->uartType = UART_8250;
                    431:        }
                    432: 
                    433:        // save the old interrupt handler
                    434:        _go32_dpmi_get_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo);
                    435: 
                    436:        if (p->uartType == UART_8250)
                    437:        {
                    438:                outportb (p->uart + FIFO_CONTROL_REGISTER, 0);
                    439:                if (p == handleToPort[0])
                    440:                        isr = COM1_ISR_8250;
                    441:                else
                    442:                        isr = COM2_ISR_8250;
                    443:        }
                    444:        else
                    445:        {
                    446:                outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE | FCR_RCVR_FIFO_RESET | FCR_XMIT_FIFO_RESET | FCR_TRIGGER_08);
                    447:                if (p == handleToPort[0])
                    448:                        isr = COM1_ISR_16550;
                    449:                else
                    450:                        isr = COM2_ISR_16550;
                    451:        }
                    452: 
                    453:        p->protectedModeInfo.pm_offset = (int)isr;
                    454: 
                    455:        n = _go32_dpmi_allocate_iret_wrapper(&p->protectedModeInfo);
                    456:        if (n)
                    457:        {
                    458:                Con_Printf("serial: protected mode callback allocation failed\n");
                    459:                return;
                    460:        }
                    461: 
                    462:        // disable interrupts at the processor
                    463:        disable();
                    464: 
                    465:        // install our interrupt handlers now
                    466:        _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeInfo);
                    467: 
                    468:        // enable our interrupt at the PIC
                    469:        outportb (0x21, inportb (0x21) & ~(1<<p->irq));
                    470: 
                    471:        // enable interrupts at the processor
                    472:        enable();
                    473: 
                    474:        // enable interrupts at the PIC
                    475:        outportb (0x20, 0xc2);
                    476: 
                    477:        // set baud rate & line control
                    478:        outportb (p->uart + LINE_CONTROL_REGISTER, LCR_DLAB | p->lineControl);
                    479:        outportb (p->uart, p->baudBits);
                    480:        outportb (p->uart + 1, 0);
                    481:        outportb (p->uart + LINE_CONTROL_REGISTER, p->lineControl);
                    482: 
                    483:        // set modem control register & enable uart interrupt generation
                    484:        outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR);
                    485: 
                    486:        // enable the individual interrupts at the uart
                    487:        outportb (p->uart + INTERRUPT_ENABLE_REGISTER, IER_RX_DATA_READY | IER_TX_HOLDING_REGISTER_EMPTY | IER_LINE_STATUS | IER_MODEM_STATUS);
                    488: 
                    489:        p->enabled = true;
                    490: }
                    491: 
                    492: 
                    493: static void ComPort_Disable(ComPort *p)
                    494: {
                    495:        if (!p->enabled)
                    496:        {
                    497:                Con_Printf("Already disabled\n");
                    498:                return;
                    499:        }
                    500: 
                    501:        // disable interrupts at the uart
                    502:        outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0);
                    503: 
                    504:        // disable our interrupt at the PIC
                    505:        outportb (0x21, inportb (0x21) | (1<<p->irq));
                    506: 
                    507:        // disable interrupts at the processor
                    508:        disable();
                    509: 
                    510:        // restore the old interrupt handler
                    511:        _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo);
                    512:        _go32_dpmi_free_iret_wrapper(&p->protectedModeInfo);
                    513: 
                    514:        // enable interrupts at the processor
                    515:        enable();
                    516: 
                    517:        p->enabled = false;
                    518: }
                    519: 
                    520: 
                    521: static int CheckStatus (ComPort *p)
                    522: {
                    523:        int             ret = 0;
                    524: 
                    525:        if (p->statusUpdated)
                    526:        {
                    527:                p->statusUpdated = false;
                    528: 
                    529:                if (p->lineStatus & (LSR_OVERRUN_ERROR | LSR_PARITY_ERROR | LSR_FRAMING_ERROR | LSR_BREAK_DETECT))
                    530:                {
                    531:                        if (p->lineStatus & LSR_OVERRUN_ERROR)
                    532:                                Con_DPrintf ("Serial overrun error\n");
                    533:                        if (p->lineStatus & LSR_PARITY_ERROR)
                    534:                                Con_DPrintf ("Serial parity error\n");
                    535:                        if (p->lineStatus & LSR_FRAMING_ERROR)
                    536:                                Con_DPrintf ("Serial framing error\n");
                    537:                        if (p->lineStatus & LSR_BREAK_DETECT)
                    538:                                Con_DPrintf ("Serial break detect\n");
                    539:                        ret = ERR_TTY_LINE_STATUS;
                    540:                }
                    541: 
                    542:                if ((p->modemStatus & MODEM_STATUS_MASK) != MODEM_STATUS_MASK)
                    543:                {
                    544:                        if (!(p->modemStatus & MSR_CTS))
                    545:                                Con_Printf ("Serial lost CTS\n");
                    546:                        if (!(p->modemStatus & MSR_DSR))
                    547:                                Con_Printf ("Serial lost DSR\n");
                    548:                        if (!(p->modemStatus & MSR_CD))
                    549:                                Con_Printf ("Serial lost Carrier\n");
                    550:                        ret = ERR_TTY_MODEM_STATUS;
                    551:                }
                    552:        }
                    553: 
                    554:        return ret;
                    555: }
                    556: 
                    557: 
                    558: static void Modem_Init(ComPort *p)
                    559: {
                    560:        double  start;
                    561:        char    *response;
                    562: 
                    563:        Con_Printf ("Initializing modem...\n");
                    564: 
                    565:        // write 0 to MCR, wait 1/2 sec, then write the real value back again
                    566:        // I got this from the guys at head-to-head who say it's necessary.
                    567:        outportb(p->uart + MODEM_CONTROL_REGISTER, 0);
                    568:        start = Sys_FloatTime();
                    569:        while ((Sys_FloatTime() - start) < 0.5)
                    570:                ;
                    571:        outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR);
                    572:        start = Sys_FloatTime();
                    573:        while ((Sys_FloatTime() - start) < 0.25)
                    574:                ;
                    575: 
                    576:        if (*p->clear)
                    577:        {
                    578:                Modem_Command (p, p->clear);
                    579:                start = Sys_FloatTime();
                    580:                while(1)
                    581:                {
                    582:                        if ((Sys_FloatTime() - start) > 3.0)
                    583:                        {
                    584:                                Con_Printf("No response - clear failed\n");
1.1.1.3 ! root      585:                                p->enabled = false;
        !           586:                                goto failed;
1.1       root      587:                        }
                    588:                        response = Modem_Response(p);
                    589:                        if (!response)
                    590:                                continue;
                    591:                        if (Q_strncmp(response, "OK", 2) == 0)
                    592:                                break;
                    593:                        if (Q_strncmp(response, "ERROR", 5) == 0)
1.1.1.3 ! root      594:                        {
        !           595:                                p->enabled = false;
        !           596:                                goto failed;
        !           597:                        }
1.1       root      598:                }
                    599:        }
                    600: 
                    601:        if (*p->startup)
                    602:        {
                    603:                Modem_Command (p, p->startup);
                    604:                start = Sys_FloatTime();
                    605:                while(1)
                    606:                {
                    607:                        if ((Sys_FloatTime() - start) > 3.0)
                    608:                        {
                    609:                                Con_Printf("No response - init failed\n");
1.1.1.3 ! root      610:                                p->enabled = false;
        !           611:                                goto failed;
1.1       root      612:                        }
                    613:                        response = Modem_Response(p);
                    614:                        if (!response)
                    615:                                continue;
                    616:                        if (Q_strncmp(response, "OK", 2) == 0)
                    617:                                break;
                    618:                        if (Q_strncmp(response, "ERROR", 5) == 0)
1.1.1.3 ! root      619:                        {
        !           620:                                p->enabled = false;
        !           621:                                goto failed;
        !           622:                        }
1.1       root      623:                }
                    624:        }
                    625: 
                    626:        p->modemInitialized = true;
1.1.1.3 ! root      627:        return;
        !           628: 
        !           629: failed:
        !           630:        if (m_return_onerror)
        !           631:        {
        !           632:                key_dest = key_menu;
        !           633:                m_state = m_return_state;
        !           634:                m_return_onerror = false;
        !           635:                Q_strcpy(m_return_reason, "Initialization Failed");
        !           636:        }
        !           637:        return;
1.1       root      638: }
                    639: 
                    640: 
                    641: void TTY_Enable(int handle)
                    642: {
                    643:        ComPort *p;
                    644: 
                    645:        p = handleToPort [handle];
                    646:        if (p->enabled)
                    647:                return;
                    648: 
                    649:        ComPort_Enable(p);
                    650: 
                    651:        if (p->useModem && !p->modemInitialized)
                    652:                Modem_Init (p);
                    653: }
                    654: 
                    655: 
                    656: int TTY_Open(int serialPortNumber)
                    657: {
                    658:        return serialPortNumber;
                    659: }
                    660: 
                    661: 
                    662: void TTY_Close(int handle)
                    663: {
                    664:        ComPort *p;
                    665:        double          startTime;
                    666: 
                    667:        p = handleToPort [handle];
                    668: 
                    669:        startTime = Sys_FloatTime();
                    670:        while ((Sys_FloatTime() - startTime) < 1.0)
                    671:                if (EMPTY(p->outputQueue))
                    672:                        break;
                    673: 
                    674:        if (p->useModem)
                    675:        {
                    676:                if (p->modemConnected)
                    677:                        Modem_Hangup(p);
                    678:        }
                    679: }
                    680: 
                    681: 
                    682: int TTY_ReadByte(int handle)
                    683: {
                    684:        int             ret;
                    685:        ComPort *p;
                    686: 
                    687:        p = handleToPort [handle];
                    688: 
                    689:        if ((ret = CheckStatus (p)) != 0)
                    690:                return ret;
                    691:        
                    692:        if (EMPTY (p->inputQueue))
                    693:                return ERR_TTY_NODATA;
                    694: 
                    695:        DEQUEUE (p->inputQueue, ret);
                    696:        return (ret & 0xff);
                    697: }
                    698: 
                    699: 
                    700: int TTY_WriteByte(int handle, byte data)
                    701: {
                    702:        ComPort *p;
                    703: 
                    704:        p = handleToPort [handle];
                    705:        if (FULL(p->outputQueue))
                    706:                return -1;
                    707: 
                    708:        ENQUEUE (p->outputQueue, data);
                    709:        return 0;
                    710: }
                    711: 
                    712: 
                    713: void TTY_Flush(int handle)
                    714: {
                    715:        byte b;
                    716:        ComPort *p;
                    717: 
                    718:        p = handleToPort [handle];
                    719: 
                    720:        if (inportb (p->uart + LINE_STATUS_REGISTER ) & LSR_TRANSMITTER_EMPTY)
                    721:        {
                    722:                DEQUEUE (p->outputQueue, b);
                    723:                outportb(p->uart, b);
                    724:        }
                    725: }
                    726: 
                    727: 
                    728: int TTY_Connect(int handle, char *host)
                    729: {
                    730:        double  start;
                    731:        ComPort *p;
1.1.1.3 ! root      732:        char    *response = NULL;
        !           733:        keydest_t       save_key_dest;
1.1       root      734:        byte    dialstring[64];
                    735:        byte    b;
                    736: 
                    737:        p = handleToPort[handle];
                    738: 
                    739:        if ((p->modemStatus & MODEM_STATUS_MASK) != MODEM_STATUS_MASK)
                    740:        {
                    741:                Con_Printf ("Serial: line not ready (");
                    742:                if ((p->modemStatus & MSR_CTS) == 0)
                    743:                        Con_Printf(" CTS");
                    744:                if ((p->modemStatus & MSR_DSR) == 0)
                    745:                        Con_Printf(" DSR");
                    746:                if ((p->modemStatus & MSR_CD) == 0)
                    747:                        Con_Printf(" CD");
                    748:                Con_Printf(" )");
                    749:                return -1;
                    750:        }
                    751: 
                    752:        // discard any scraps in the input buffer
                    753:        while (! EMPTY (p->inputQueue))
                    754:                DEQUEUE (p->inputQueue, b);
                    755: 
                    756:        CheckStatus (p);
                    757: 
                    758:        if (p->useModem)
                    759:        {
1.1.1.3 ! root      760:                save_key_dest = key_dest;
        !           761:                key_dest = key_console;
        !           762:                key_count = -2;
        !           763: 
1.1       root      764:                Con_Printf ("Dialing...\n");
                    765:                sprintf(dialstring, "AT D%c %s\r", p->dialType, host);
                    766:                Modem_Command (p, dialstring);
                    767:                start = Sys_FloatTime();
                    768:                while(1)
                    769:                {
                    770:                        if ((Sys_FloatTime() - start) > 60.0)
                    771:                        {
                    772:                                Con_Printf("Dialing failure!\n");
                    773:                                break;
                    774:                        }
1.1.1.3 ! root      775: 
        !           776:                        Sys_SendKeyEvents ();
        !           777:                        if (key_count == 0)
        !           778:                        {
        !           779:                                if (key_lastpress != K_ESCAPE)
        !           780:                                {
        !           781:                                        key_count = -2;
        !           782:                                        continue;
        !           783:                                }
        !           784:                                Con_Printf("Aborting...\n");
        !           785:                                while ((Sys_FloatTime() - start) < 5.0)
        !           786:                                        ;
        !           787:                                disable();
        !           788:                                p->outputQueue.head = p->outputQueue.tail = 0;
        !           789:                                p->inputQueue.head = p->inputQueue.tail = 0;
        !           790:                                outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) & ~MCR_DTR);
        !           791:                                enable();
        !           792:                                start = Sys_FloatTime();
        !           793:                                while ((Sys_FloatTime() - start) < 0.75)
        !           794:                                        ;
        !           795:                                outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) | MCR_DTR);
        !           796:                                response = "Aborted";
        !           797:                                break;
        !           798:                        }
        !           799: 
1.1       root      800:                        response = Modem_Response(p);
                    801:                        if (!response)
                    802:                                continue;
                    803:                        if (Q_strncmp(response, "CONNECT", 7) == 0)
                    804:                        {
1.1.1.3 ! root      805:                                disable();
1.1       root      806:                                p->modemRang = true;
                    807:                                p->modemConnected = true;
1.1.1.3 ! root      808:                                p->outputQueue.head = p->outputQueue.tail = 0;
        !           809:                                p->inputQueue.head = p->inputQueue.tail = 0;
        !           810:                                enable();
        !           811:                                key_dest = save_key_dest;
        !           812:                                key_count = 0;
        !           813:                                m_return_onerror = false;
1.1       root      814:                                return 0;
                    815:                        }
                    816:                        if (Q_strncmp(response, "NO CARRIER", 10) == 0)
                    817:                                break;
                    818:                        if (Q_strncmp(response, "NO DIALTONE", 11) == 0)
                    819:                                break;
                    820:                        if (Q_strncmp(response, "NO DIAL TONE", 12) == 0)
                    821:                                break;
                    822:                        if (Q_strncmp(response, "NO ANSWER", 9) == 0)
                    823:                                break;
                    824:                        if (Q_strncmp(response, "BUSY", 4) == 0)
                    825:                                break;
                    826:                        if (Q_strncmp(response, "ERROR", 5) == 0)
                    827:                                break;
                    828:                }
1.1.1.3 ! root      829:                key_dest = save_key_dest;
        !           830:                key_count = 0;
        !           831:                if (m_return_onerror)
        !           832:                {
        !           833:                        key_dest = key_menu;
        !           834:                        m_state = m_return_state;
        !           835:                        m_return_onerror = false;
        !           836:                        Q_strncpy(m_return_reason, response, 31);
        !           837:                }
1.1       root      838:                return -1;
                    839:        }
1.1.1.3 ! root      840:        m_return_onerror = false;
1.1       root      841:        return 0;
                    842: }
                    843: 
                    844: 
                    845: void TTY_Disconnect(int handle)
                    846: {
                    847:        ComPort *p;
                    848: 
                    849:        p = handleToPort[handle];
                    850: 
                    851:        if (p->useModem && p->modemConnected)
                    852:                Modem_Hangup(p);
                    853: }
                    854: 
                    855: 
                    856: qboolean TTY_CheckForConnection(int handle)
                    857: {
                    858:        ComPort *p;
                    859: 
                    860:        p = handleToPort[handle];
                    861: 
                    862:        CheckStatus (p);
                    863: 
                    864:        if (p->useModem)
                    865:        {
                    866:                if (!p->modemRang)
                    867:                {
                    868:                        if (!Modem_Response(p))
                    869:                                return false;
                    870: 
                    871:                        if (Q_strncmp(p->buffer, "RING", 4) == 0)
                    872:                        {
                    873:                                Modem_Command (p, "ATA");
                    874:                                p->modemRang = true;
                    875:                                p->timestamp = net_time;
                    876:                        }
                    877:                        return false;
                    878:                }
                    879:                if (!p->modemConnected)
                    880:                {
                    881:                        if ((net_time - p->timestamp) > 35.0)
                    882:                        {
                    883:                                Con_Printf("Unable to establish modem connection\n");
                    884:                                p->modemRang = false;
                    885:                                return false;
                    886:                        }
                    887: 
                    888:                        if (!Modem_Response(p))
                    889:                                return false;
                    890: 
                    891:                        if (Q_strncmp (p->buffer, "CONNECT", 7) != 0)
                    892:                                return false;
                    893: 
1.1.1.3 ! root      894:                        disable();
1.1       root      895:                        p->modemConnected = true;
1.1.1.3 ! root      896:                        p->outputQueue.head = p->outputQueue.tail = 0;
        !           897:                        p->inputQueue.head = p->inputQueue.tail = 0;
        !           898:                        enable();
1.1       root      899:                        Con_Printf("Modem Connect\n");
                    900:                        return true;
                    901:                }
                    902:                return true;
                    903:        }
                    904: 
                    905:        // direct connect case
                    906:        if (EMPTY (p->inputQueue))
                    907:                return false;
                    908:        return true;
                    909: }
                    910: 
                    911: 
                    912: qboolean TTY_IsEnabled(int serialPortNumber)
                    913: {
                    914:        return handleToPort[serialPortNumber]->enabled;
                    915: }
                    916: 
                    917: 
                    918: qboolean TTY_IsModem(int serialPortNumber)
                    919: {
                    920:        return handleToPort[serialPortNumber]->useModem;
                    921: }
                    922: 
                    923: 
                    924: qboolean TTY_OutputQueueIsEmpty(int handle)
                    925: {
                    926:        return EMPTY(handleToPort[handle]->outputQueue);
                    927: }
                    928: 
                    929: 
                    930: void Com_f (void)
                    931: {
                    932:        ComPort *p;
                    933:        int             portNumber;
                    934:        int             i;
                    935:        int             n;
                    936: 
                    937:        // first, determine which port they're messing with
                    938:        portNumber = Q_atoi(Cmd_Argv (0) + 3) - 1;
                    939:        if (portNumber > 1)
                    940:                return;
                    941:        p = handleToPort[portNumber];
                    942: 
                    943:        if (Cmd_Argc() == 1)
                    944:        {
                    945:                Con_Printf("Settings for COM%i\n", portNumber + 1);
                    946:                Con_Printf("enabled:   %s\n", p->enabled ? "true" : "false");
                    947:                Con_Printf("uart:      ");
                    948:                if (p->uartType == UART_AUTO)
                    949:                        Con_Printf("auto\n");
                    950:                else if (p->uartType == UART_8250)
                    951:                        Con_Printf("8250\n");
                    952:                else
                    953:                        Con_Printf("16550\n");
                    954:                Con_Printf("port:      %x\n", p->uart);
                    955:                Con_Printf("irq:       %i\n", p->irq);
                    956:                Con_Printf("baud:      %i\n", 115200 / p->baudBits);    
                    957:                Con_Printf("CTS:       %s\n", (p->modemStatusIgnore & MSR_CTS) ? "ignored" : "honored");
                    958:                Con_Printf("DSR:       %s\n", (p->modemStatusIgnore & MSR_DSR) ? "ignored" : "honored");
                    959:                Con_Printf("CD:        %s\n", (p->modemStatusIgnore & MSR_CD) ? "ignored" : "honored");
                    960:                if (p->useModem)
                    961:                {
                    962:                        Con_Printf("type:      Modem\n");
                    963:                        Con_Printf("clear:     %s\n", p->clear);
                    964:                        Con_Printf("startup:   %s\n", p->startup);
                    965:                        Con_Printf("shutdown:  %s\n", p->shutdown);
                    966:                }
                    967:                else
                    968:                        Con_Printf("type:      Direct connect\n");
                    969: 
                    970:                return;
                    971:        }
                    972: 
                    973: 
                    974:        if (Cmd_CheckParm ("disable"))
                    975:        {
                    976:                if (p->enabled)
                    977:                        ComPort_Disable(p);
                    978:                p->modemInitialized = false;
                    979:                return;
                    980:        }
                    981: 
                    982:        if (Cmd_CheckParm ("reset"))
                    983:        {
                    984:                ComPort_Disable(p);
                    985:                ResetComPortConfig (p);
                    986:                return;
                    987:        }
                    988: 
                    989:        if ((i = Cmd_CheckParm ("port")) != 0)
                    990:        {
                    991:                if (p->enabled)
                    992:                        {
                    993:                                Con_Printf("COM port must be disabled to change port\n");
                    994:                                return;
                    995:                        }
                    996:                p->uart = Q_atoi (Cmd_Argv (i+1));
                    997:        }
                    998: 
                    999:        if ((i = Cmd_CheckParm ("irq")) != 0)
                   1000:        {
                   1001:                if (p->enabled)
                   1002:                        {
                   1003:                                Con_Printf("COM port must be disabled to change irq\n");
                   1004:                                return;
                   1005:                        }
                   1006:                p->irq = Q_atoi (Cmd_Argv (i+1));
                   1007:        }
                   1008: 
                   1009:        if ((i = Cmd_CheckParm ("baud")) != 0)
                   1010:        {
                   1011:                if (p->enabled)
                   1012:                        {
                   1013:                                Con_Printf("COM port must be disabled to change baud\n");
                   1014:                                return;
                   1015:                        }
                   1016:                n = Q_atoi (Cmd_Argv (i+1));
                   1017:                if (n == 0)
                   1018:                        Con_Printf("Invalid baud rate specified\n");
                   1019:                else
                   1020:                        p->baudBits = 115200 / n;
                   1021:        }
                   1022: 
                   1023:        if (Cmd_CheckParm ("8250"))
                   1024:        {
                   1025:                if (p->enabled)
                   1026:                        {
                   1027:                                Con_Printf("COM port must be disabled to change uart\n");
                   1028:                                return;
                   1029:                        }
                   1030:                p->uartType = UART_8250;
                   1031:                }
                   1032:        if (Cmd_CheckParm ("16550"))
                   1033:        {
                   1034:                if (p->enabled)
                   1035:                        {
                   1036:                                Con_Printf("COM port must be disabled to change uart\n");
                   1037:                                return;
                   1038:                        }
                   1039:                p->uartType = UART_16550;
                   1040:        }
                   1041:        if (Cmd_CheckParm ("auto"))
                   1042:        {
                   1043:                if (p->enabled)
                   1044:                        {
                   1045:                                Con_Printf("COM port must be disabled to change uart\n");
                   1046:                                return;
                   1047:                        }
                   1048:                p->uartType = UART_AUTO;
                   1049:        }
                   1050: 
                   1051:        if (Cmd_CheckParm ("pulse"))
                   1052:                p->dialType = 'P';
                   1053:        if (Cmd_CheckParm ("tone"))
                   1054:                p->dialType = 'T';
                   1055: 
                   1056:        if (Cmd_CheckParm ("direct"))
                   1057:                p->useModem = false;
                   1058:        if (Cmd_CheckParm ("modem"))
                   1059:                p->useModem = true;
                   1060: 
                   1061:        if ((i = Cmd_CheckParm ("clear")) != 0)
                   1062:        {
                   1063:                Q_strncpy (p->clear, Cmd_Argv (i+1), 16);
                   1064:        }
                   1065: 
                   1066:        if ((i = Cmd_CheckParm ("startup")) != 0)
                   1067:        {
                   1068:                Q_strncpy (p->startup, Cmd_Argv (i+1), 32);
                   1069:                p->modemInitialized = false;
                   1070:        }
                   1071: 
                   1072:        if ((i = Cmd_CheckParm ("shutdown")) != 0)
                   1073:        {
                   1074:                Q_strncpy (p->shutdown, Cmd_Argv (i+1), 16);
                   1075:        }
                   1076: 
                   1077:        if (Cmd_CheckParm ("-cts"))
                   1078:        {
                   1079:                p->modemStatusIgnore |= MSR_CTS;
                   1080:                p->modemStatus |= MSR_CTS;
                   1081:        }
                   1082: 
                   1083:        if (Cmd_CheckParm ("+cts"))
                   1084:        {
                   1085:                p->modemStatusIgnore &= (~MSR_CTS);
                   1086:                p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                   1087:        }
                   1088: 
                   1089:        if (Cmd_CheckParm ("-dsr"))
                   1090:        {
                   1091:                p->modemStatusIgnore |= MSR_DSR;
                   1092:                p->modemStatus |= MSR_DSR;
                   1093:        }
                   1094: 
                   1095:        if (Cmd_CheckParm ("+dsr"))
                   1096:        {
                   1097:                p->modemStatusIgnore &= (~MSR_DSR);
                   1098:                p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                   1099:        }
                   1100: 
                   1101:        if (Cmd_CheckParm ("-cd"))
                   1102:        {
                   1103:                p->modemStatusIgnore |= MSR_CD;
                   1104:                p->modemStatus |= MSR_CD;
                   1105:        }
                   1106: 
                   1107:        if (Cmd_CheckParm ("+cd"))
                   1108:        {
                   1109:                p->modemStatusIgnore &= (~MSR_CD);
                   1110:                p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore;
                   1111:        }
                   1112: 
                   1113:        if (Cmd_CheckParm ("enable"))
                   1114:        {
                   1115:                if (!p->enabled)
                   1116:                        ComPort_Enable(p);
                   1117:                if (p->useModem && !p->modemInitialized)
                   1118:                        Modem_Init (p);
                   1119:        }
                   1120: }
                   1121: 
                   1122: 
                   1123: int TTY_Init(void)
                   1124: {
                   1125:        int             n;
                   1126:        ComPort *p;
                   1127: 
                   1128:        for (n = 0; n < NUM_COM_PORTS; n++)
                   1129:        {
                   1130:                p = (ComPort *)Hunk_AllocName(sizeof(ComPort), "comport");
                   1131:                if (p == NULL)
                   1132:                        Sys_Error("Hunk alloc failed for com port\n");
                   1133:                p->next = portList;
                   1134:                portList = p;
                   1135:                handleToPort[n] = p;
                   1136:                p->portNumber = n;
                   1137:                p->dialType = 'T';
                   1138:                sprintf(p->name, "com%u", n+1);
                   1139:                Cmd_AddCommand (p->name, Com_f);
                   1140:                ResetComPortConfig (p);
                   1141:        }
                   1142: 
                   1143:        GetComPortConfig = TTY_GetComPortConfig;
                   1144:        SetComPortConfig = TTY_SetComPortConfig;
                   1145:        GetModemConfig = TTY_GetModemConfig;
                   1146:        SetModemConfig = TTY_SetModemConfig;
                   1147: 
                   1148:        return 0;
                   1149: }
                   1150: 
                   1151: 
                   1152: void TTY_Shutdown(void)
                   1153: {
                   1154:        int             n;
                   1155:        ComPort *p;
                   1156: 
                   1157:        for (n = 0; n < NUM_COM_PORTS; n++)
                   1158:        {
                   1159:                p = handleToPort[n];
                   1160:                if (p->enabled)
                   1161:                {
                   1162:                        while (p->modemConnected)
                   1163:                                NET_Poll();
                   1164:                        ComPort_Disable (p);
                   1165:                }
                   1166:        }
                   1167: }
                   1168: 
                   1169: 
                   1170: static int Modem_Command(ComPort *p, char *commandString)
                   1171: {
                   1172:        byte    b;
                   1173: 
                   1174:        if (CheckStatus (p))
                   1175:                return -1;
                   1176: 
1.1.1.3 ! root     1177:        disable();
        !          1178:        p->outputQueue.head = p->outputQueue.tail = 0;
        !          1179:        p->inputQueue.head = p->inputQueue.tail = 0;
        !          1180:        enable();
        !          1181:        p->bufferUsed = 0;
        !          1182: 
1.1       root     1183:        while (*commandString)
                   1184:                ENQUEUE (p->outputQueue, *commandString++);
                   1185:        ENQUEUE (p->outputQueue, '\r');
                   1186: 
                   1187:        // get the transmit rolling
                   1188:        DEQUEUE (p->outputQueue, b);
                   1189:        outportb(p->uart, b);
                   1190: 
                   1191:        return 0;
                   1192: }
                   1193: 
                   1194: 
                   1195: static char *Modem_Response(ComPort *p)
                   1196: {
                   1197:        byte    b;
                   1198: 
                   1199:        if (CheckStatus (p))
                   1200:                return NULL;
                   1201: 
                   1202:        while (! EMPTY(p->inputQueue))
                   1203:        {
                   1204:                DEQUEUE (p->inputQueue, b);
1.1.1.3 ! root     1205: 
        !          1206:                if (p->bufferUsed == (sizeof(p->buffer) - 1))
        !          1207:                        b = '\r';
        !          1208: 
        !          1209:                if (b == '\r' && p->bufferUsed)
1.1       root     1210:                {
                   1211:                        p->buffer[p->bufferUsed] = 0;
                   1212:                        Con_Printf("%s\n", p->buffer);
                   1213:                        SCR_UpdateScreen ();
                   1214:                        p->bufferUsed = 0;
                   1215:                        return p->buffer;
                   1216:                }
1.1.1.3 ! root     1217: 
1.1       root     1218:                if (b < ' ' || b > 'z')
                   1219:                        continue;
                   1220:                p->buffer[p->bufferUsed] = b;
                   1221:                p->bufferUsed++;
                   1222:        }
                   1223: 
                   1224:        return NULL;
                   1225: }
                   1226: 
                   1227: 
                   1228: static void Modem_Hangup2(ComPort *p);
                   1229: static void Modem_Hangup3(ComPort *p);
                   1230: static void Modem_Hangup4(ComPort *p);
                   1231: 
                   1232: static void Modem_Hangup(ComPort *p)
                   1233: {
                   1234:        Con_Printf("Hanging up modem...\n");
1.1.1.3 ! root     1235:        disable();
1.1       root     1236:        p->modemRang = false;
1.1.1.3 ! root     1237:        p->outputQueue.head = p->outputQueue.tail = 0;
        !          1238:        p->inputQueue.head = p->inputQueue.tail = 0;
1.1       root     1239:        outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) & ~MCR_DTR);
1.1.1.3 ! root     1240:        enable();
1.1       root     1241:        p->poll.procedure = Modem_Hangup2;
                   1242:        p->poll.arg = p;
                   1243:        SchedulePollProcedure(&p->poll, 1.5);
                   1244: }
                   1245: 
                   1246: static void Modem_Hangup2(ComPort *p)
                   1247: {
                   1248:        outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) | MCR_DTR);
                   1249:        Modem_Command(p, "+++");
                   1250:        p->poll.procedure = Modem_Hangup3;
                   1251:        SchedulePollProcedure(&p->poll, 1.5);
                   1252: }
                   1253: 
                   1254: static void Modem_Hangup3(ComPort *p)
                   1255: {
                   1256:        Modem_Command(p, p->shutdown);
                   1257:        p->poll.procedure = Modem_Hangup4;
                   1258:        SchedulePollProcedure(&p->poll, 1.5);
                   1259: }
                   1260: 
                   1261: static void Modem_Hangup4(ComPort *p)
                   1262: {
                   1263:        Modem_Response(p);
                   1264:        Con_Printf("Hangup complete\n");
                   1265:        p->modemConnected = false;
                   1266: }

unix.superglobalmegacorp.com

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