www.pudn.com > COS0.0.1.rar > sout.c
/* sout.c - simple polled (no interrupts) Serial OUTput, for debugging Author: Paul Barker Part of: COS Created: 10/09/04 Last Modified: 10/09/04 This is based on code from: http://my.execpc.com/~geezer/osd/serial/pollout.c (see http://my.execpc.com/~geezer/osd) This code is public domain. This is intended to be self contained except for the headers, (ie. no external function calls). */ #include#include static word_t port_table[4] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; static word_t my_flags = 0; // change this if io is too slow/fast #define SLOW_COUNT 5 // slow down io so that old serial controllers can cope void outb_slow(u8_t value, u16_t addr) { int a; outb(value, addr); a = SLOW_COUNT; while (a--); } u8_t inb_slow(u16_t addr) { int a; u8_t b = inb(addr); a = SLOW_COUNT; while (a--); return b; } bool_t sout(u8_t ch, u8_t port) // port is 0-based index { u16_t io_addr; count_t c; // translate base port if (port & 0xFC) return False; // port out of range io_addr = port_table[port]; // check if this port is initialised if (!(my_flags & (1 << port))) { // the port has not been initialised so do this now outb_slow(0x80, io_addr + 3); // 115200 baud outb_slow(1, io_addr); outb_slow(0, io_addr + 1); // 8 data bits + 1 stop bit (methinks) outb_slow(0x03, io_addr + 3); // all interrupts disabled outb_slow(0, io_addr + 1); // turn off FIFO, if any outb_slow(0, io_addr + 2); // loopback off, interrupts (Out2) off, Out1/RTS/DTR off outb_slow(0, io_addr + 4); my_flags |= 1 << port; } // wait for the transmitter to be ready, with sensible time out for (c = 0; c < 0x10000; c++) { if (inb_slow(io_addr + 5) & 0x40) goto ready; } return False; ready: outb_slow(ch, io_addr); return True; }