2011-02-11 06:45:29 +03:00
|
|
|
/**
|
|
|
|
* Serial Port Driver
|
2011-04-06 04:12:08 +04:00
|
|
|
* vim:tabstop=4
|
|
|
|
* vim:noexpandtab
|
2011-02-11 06:45:29 +03:00
|
|
|
*/
|
|
|
|
#include <system.h>
|
|
|
|
|
|
|
|
#define SERIAL_PORT_A 0x3F8
|
|
|
|
#define SERIAL_PORT_B 0x2F8
|
|
|
|
#define SERIAL_PORT_C 0x3E8
|
|
|
|
#define SERIAL_PORT_D 0x2E8
|
|
|
|
|
2011-02-20 00:27:41 +03:00
|
|
|
void
|
|
|
|
serial_handler(
|
|
|
|
struct regs *r
|
|
|
|
) {
|
|
|
|
char serial = serial_recv();
|
|
|
|
/*
|
|
|
|
* Fix the serial input assuming it is ascii
|
|
|
|
*/
|
|
|
|
switch (serial) {
|
|
|
|
case 127:
|
|
|
|
serial = 0x08;
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
serial = '\n';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (keyboard_buffer_handler) {
|
|
|
|
keyboard_buffer_handler(serial);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-11 06:45:29 +03:00
|
|
|
void
|
|
|
|
serial_install() {
|
|
|
|
/* We will initialize the first serial port */
|
|
|
|
outportb(SERIAL_PORT_A + 1, 0x00);
|
2011-02-20 00:27:41 +03:00
|
|
|
outportb(SERIAL_PORT_A + 3, 0x80); /* Enable divisor mode */
|
|
|
|
outportb(SERIAL_PORT_A + 0, 0x03); /* Div Low: 03 Set the port to 38400 bps */
|
|
|
|
outportb(SERIAL_PORT_A + 1, 0x00); /* Div High: 00 */
|
2011-02-11 06:45:29 +03:00
|
|
|
outportb(SERIAL_PORT_A + 3, 0x03);
|
|
|
|
outportb(SERIAL_PORT_A + 2, 0xC7);
|
|
|
|
outportb(SERIAL_PORT_A + 4, 0x0B);
|
2011-02-20 00:27:41 +03:00
|
|
|
irq_install_handler(4, serial_handler); /* Install the serial input handler */
|
|
|
|
outportb(SERIAL_PORT_A + 1, 0x01); /* Enable interrupts on receive */
|
2011-02-11 06:45:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
serial_rcvd() {
|
|
|
|
return inportb(SERIAL_PORT_A + 5) & 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char
|
|
|
|
serial_recv() {
|
|
|
|
while (serial_rcvd() == 0);
|
|
|
|
return inportb(SERIAL_PORT_A);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
serial_transmit_empty() {
|
|
|
|
return inportb(SERIAL_PORT_A + 5) & 0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
serial_send(char out) {
|
|
|
|
while (serial_transmit_empty() == 0);
|
|
|
|
outportb(SERIAL_PORT_A, out);
|
|
|
|
}
|
2011-04-05 03:51:55 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
serial_string(char * out) {
|
2011-11-18 10:00:54 +04:00
|
|
|
for (uint32_t i = 0; i < strlen(out); ++i) {
|
2011-04-05 03:51:55 +04:00
|
|
|
serial_send(out[i]);
|
|
|
|
}
|
|
|
|
}
|