diff options
Diffstat (limited to 'sys/i386/boot/io.c')
-rw-r--r-- | sys/i386/boot/io.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/sys/i386/boot/io.c b/sys/i386/boot/io.c new file mode 100644 index 0000000..ee441f0 --- /dev/null +++ b/sys/i386/boot/io.c @@ -0,0 +1,214 @@ + +/* + * Mach Operating System + * Copyright (c) 1992, 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + * + * from: Mach, Revision 2.2 92/04/04 11:35:57 rpd + * $Id: io.c,v 1.5 1994/06/15 19:09:14 jkh Exp $ + */ + +#include <i386/include/pio.h> + +#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ +#define K_STATUS 0x64 /* keyboard status */ +#define K_CMD 0x64 /* keybd ctlr command (write-only) */ + +#define K_OBUF_FUL 0x01 /* output buffer full */ +#define K_IBUF_FUL 0x02 /* input buffer full */ + +#define KC_CMD_WIN 0xd0 /* read output port */ +#define KC_CMD_WOUT 0xd1 /* write output port */ +#define KB_A20 0xdf /* enable A20, + enable output buffer full interrupt + enable data line + enable clock line */ + +/* + * Gate A20 for high memory + */ +unsigned char x_20 = KB_A20; +gateA20() +{ +#ifdef IBM_L40 + outb(0x92, 0x2); +#else IBM_L40 + while (inb(K_STATUS) & K_IBUF_FUL); + while (inb(K_STATUS) & K_OBUF_FUL) + (void)inb(K_RDWR); + + outb(K_CMD, KC_CMD_WOUT); + while (inb(K_STATUS) & K_IBUF_FUL); + outb(K_RDWR, x_20); + while (inb(K_STATUS) & K_IBUF_FUL); +#endif IBM_L40 +} + +/* printf - only handles %d as decimal, %c as char, %s as string */ + +printf(format,data) + char *format; + int data; +{ + int *dataptr = &data; + char c; + + reset_twiddle(); + while (c = *format++) + if (c != '%') + putchar(c); + else + switch (c = *format++) { + case 'd': { + int num = *dataptr++; + char buf[10], *ptr = buf; + if (num<0) { + num = -num; + putchar('-'); + } + do + *ptr++ = '0'+num%10; + while (num /= 10); + do + putchar(*--ptr); + while (ptr != buf); + break; + } + case 'x': { + int num = *dataptr++, dig; + char buf[8], *ptr = buf; + do + *ptr++ = (dig=(num&0xf)) > 9? + 'a' + dig - 10 : + '0' + dig; + while (num >>= 4); + do + putchar(*--ptr); + while (ptr != buf); + break; + } + case 'c': putchar((*dataptr++)&0xff); break; + case 's': { + char *ptr = (char *)*dataptr++; + while (c = *ptr++) + putchar(c); + break; + } + } +} + +putchar(c) +{ + if (c == '\n') + putc('\r'); + putc(c); +} + +getchar() +{ + int c; + + if ((c=getc()) == '\r') + c = '\n'; + if (c == '\b') { + putchar('\b'); + putchar(' '); + } + putchar(c); + return(c); +} + +#if BOOTWAIT +spinwait(i) +int i; +{ + while (--i >= 0) + (void)inb(0x84); +} +#endif + +gets(buf) +char *buf; +{ + int i; + char *ptr=buf; + +#if BOOTWAIT + for (i = BOOTWAIT; i>0; spinwait(10000),i--) +#endif + if (ischar()) + for (;;) + switch(*ptr = getchar() & 0xff) { + case '\n': + case '\r': + *ptr = '\0'; + return 1; + case '\b': + if (ptr > buf) ptr--; + continue; + default: + ptr++; + } + return 0; +} + +strcmp(s1, s2) +char *s1, *s2; +{ + while (*s1 == *s2) { + if (!*s1++) + return 0; + s2++; + } + return 1; +} + +bcopy(from, to, len) +char *from, *to; +int len; +{ + while (len-- > 0) + *to++ = *from++; +} + +static int tw_on; +static int tw_pos; +static char tw_chars[] = "|/-\\"; + +reset_twiddle() +{ + if (tw_on) + putchar('\b'); + tw_on = 0; + tw_pos = 0; +} + +twiddle() +{ + if (tw_on) + putchar('\b'); + else + tw_on = 1; + putchar(tw_chars[tw_pos++]); + tw_pos %= (sizeof(tw_chars) - 1); +} |