/* RS232 serial ports no longer exist. Be sure to System Include this by placing it in your start-up scripts. */ #help_index "Comm" #define UART_THR 0 #define UART_RDR 0 #define UART_BRDL 0 #define UART_IER 1 #define UART_BRDH 1 #define UART_IIR 2 #define UART_LCR 3 #define UART_MCR 4 #define UART_LSR 5 #define UART_MSR 6 #define COMf_ENABLED 0 class CComm { I64 base, flags; CFifoU8 *RX_fifo; CFifoU8 *TX_fifo; } comm_ports[5]; U0 CommHandler(I64 port) { CComm *c = &comm_ports[port]; I64 b = 0, stat; if (Bt(&c->flags, COMf_ENABLED)) { stat = InU8(c->base+UART_IIR); if (stat & 4) //RX FifoU8Insert(c->RX_fifo, InU8(c->base + UART_RDR)); if (stat & 2) { //TX if (FifoU8Remove(c->TX_fifo, &b)) OutU8(c->base + UART_THR, b); else OutU8(c->base + UART_IER, 1); //RX but no THR empty } } } interrupt U0 IRQComm3() { CommHandler(2); CommHandler(4); OutU8(PIC_1, PIC_EOI); } interrupt U0 IRQComm4() { CommHandler(1); CommHandler(3); OutU8(PIC_1, PIC_EOI); } U0 CommInit() { MemSet(&comm_ports, 0, sizeof(comm_ports)); comm_ports[1].base = 0x3F8; comm_ports[2].base = 0x2F8; comm_ports[3].base = 0x3E8; comm_ports[4].base = 0x2E8; IntEntrySet(0x23, &IRQComm3); IntEntrySet(0x24, &IRQComm4); } CommInit; public CComm *CommInit8n1(I64 port, I64 baud) { CComm *c = &comm_ports[port]; PUSHFD CLI if (LBts(&c->flags, COMf_ENABLED)) { FifoU8Del(c->RX_fifo); FifoU8Del(c->TX_fifo); } c->RX_fifo = FifoU8New(256); c->TX_fifo = FifoU8New(256); OutU8(c->base + UART_LCR, 0); //Set for IER OutU8(c->base + UART_IER, 0); //Disable all IRQ OutU8(c->base + UART_LCR, 0x80); //Enable baud rate control OutU8(c->base + UART_BRDL, (0x180 / (baud / 300)) & 0xFF); //LSB OutU8(c->base + UART_BRDH, (0x180 / (baud / 300)) / 256); //MSB OutU8(c->base + UART_LCR, 3); //8-none-1 InU8(c->base + UART_RDR); //read garbage InU8(c->base + UART_LSR); OutU8(c->base + UART_MCR, 4); OutU8(c->base + UART_IER, 0); //Disable all IRQ OutU8(c->base + UART_MCR, 0xA); //out2 and rts OutU8(PIC_1_DATA, InU8(PIC_1_DATA) & (0xFF - 0x18)); //Enable 8259 IRQ 3 & 4 OutU8(c->base + UART_IER, 1); //RX but no THR empty POPFD return c; } public U0 CommPutChar(I64 port, U8 b) { CComm *c = &comm_ports[port]; PUSHFD CLI FifoU8Insert(c->TX_fifo, b); OutU8(c->base + UART_IER, 3); //RX and THR empty POPFD Sleep(10); //!!! Remove this line!!! Linux echo_socket is too slow. } U0 CommPutS(I64 port, U8 *st) { I64 b; while (b = *st++) CommPutChar(port, b); } public U0 CommPutBlk(I64 port, U8 *buf, I64 count) { while (count--) CommPutChar(port, *buf++); } public U0 CommPrint(I64 port, U8 *format, ...) { U8 *buf = StrPrintJoin(NULL, format, argc, argv); CommPutS(port, buf); Free(buf); }