mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-03-14 03:55:06 +00:00
140 lines
2.8 KiB
HolyC
Executable file
140 lines
2.8 KiB
HolyC
Executable file
/* 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);
|
|
}
|