hschumann2/TempleOS-Source-Code
0838
1 2/* RS232 serial ports no longer exist.3Be sure to Adam Include this by placing4it in your start-up scripts.5*/6 7#help_index "Comm"8 9#define UART_THR 010#define UART_RDR 011#define UART_BRDL 012#define UART_IER 113#define UART_BRDH 114#define UART_IIR 215#define UART_LCR 316#define UART_MCR 417#define UART_LSR 518#define UART_MSR 619 20#define COMf_ENABLED 021class CComm22{23 I64 base,24 flags;25 CFifoU8 *RX_fifo;26 CFifoU8 *TX_fifo;27} comm_ports[5];28 29U0 CommHndlr(I64 port)30{31 CComm *c=&comm_ports[port];32 I64 b=0,stat;33 if (Bt(&c->flags,COMf_ENABLED)) {34 stat=InU8(c->base+UART_IIR);35 if (stat & 4) //RX36 FifoU8Ins(c->RX_fifo,InU8(c->base+UART_RDR));37 if (stat & 2) { //TX38 if (FifoU8Rem(c->TX_fifo,&b))39 OutU8(c->base+UART_THR,b);40 else41 OutU8(c->base+UART_IER,1); //RX but no THR empty42 }43 }44}45 46interrupt U0 IRQComm3()47{48 CommHndlr(2);49 CommHndlr(4);50 OutU8(0x20,0x20);51}52 53interrupt U0 IRQComm4()54{55 CommHndlr(1);56 CommHndlr(3);57 OutU8(0x20,0x20);58}59 60U0 CommInit()61{62 MemSet(&comm_ports,0,sizeof(comm_ports));63 comm_ports[1].base=0x3F8;64 comm_ports[2].base=0x2F8;65 comm_ports[3].base=0x3E8;66 comm_ports[4].base=0x2E8;67 IntEntrySet(0x23,&IRQComm3);68 IntEntrySet(0x24,&IRQComm4);69}70CommInit;71 72public CComm *CommInit8n1(I64 port,I64 baud)73{74 CComm *c=&comm_ports[port];75 76 PUSHFD77 CLI78 if (LBts(&c->flags,COMf_ENABLED)) {79 FifoU8Del(c->RX_fifo);80 FifoU8Del(c->TX_fifo);81 }82 c->RX_fifo=FifoU8New(256);83 c->TX_fifo=FifoU8New(256);84 OutU8(c->base+UART_LCR,0); //Set for IER85 OutU8(c->base+UART_IER,0); //Disable all IRQ86 OutU8(c->base+UART_LCR,0x80); //Enable baud rate control87 OutU8(c->base+UART_BRDL,(0x180/(baud/300)) & 0xFF); //LSB88 OutU8(c->base+UART_BRDH,(0x180/(baud/300)) / 256); //MSB89 OutU8(c->base+UART_LCR,3); //8-none-190 91 InU8(c->base+UART_RDR); //read garbage92 InU8(c->base+UART_LSR);93 94 OutU8(c->base+UART_MCR,4);95 OutU8(c->base+UART_IER,0); //Disable all IRQ96 OutU8(c->base+UART_MCR,0xA); //out2 and rts97 OutU8(0x21,InU8(0x21) & (0xFF-0x18)); //Enable 8259 IRQ 3 & 498 OutU8(c->base+UART_IER,1); //RX but no THR empty99 POPFD100 101 return c;102}103 104public U0 CommPutChar(I64 port,U8 b)105{106 CComm *c=&comm_ports[port];107 PUSHFD108 CLI109 FifoU8Ins(c->TX_fifo,b);110 OutU8(c->base+UART_IER,3); //RX and THR empty111 POPFD112 Sleep(10); //!!! Remove this line!!! Linux echo_socket is too slow.113}114 115U0 CommPutS(I64 port,U8 *st)116{117 I64 b;118 while (b=*st++)119 CommPutChar(port,b);120}121 122public U0 CommPutBlk(I64 port,U8 *buf,I64 cnt)123{124 while (cnt--)125 CommPutChar(port,*buf++);126}127 128public U0 CommPrint(I64 port,U8 *fmt,...)129{130 U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);131 CommPutS(port,buf);132 Free(buf);133}134 