ref: 940edd1da5336e9f2695260670a620f9047b5012
parent: ae0d5a79909f7779bb0ba3d5bdfd0d9cdd959f2f
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Feb 17 20:22:29 EST 2013
9boot: serial console support
--- a/sys/src/boot/pc/fns.h
+++ b/sys/src/boot/pc/fns.h
@@ -5,9 +5,8 @@
/* l.s */
void start(void *sp);
-int getc(void);
-int gotc(void);
-void putc(int c);
+void cgaputc(int c);
+int kbdgetc(void);
void usleep(int t);
void halt(void);
void jump(void *pc);
@@ -17,6 +16,9 @@
void close(void *f);
void unload(void);
+int getc(void);
+void putc(int c);
+
void memset(void *p, int v, int n);
void memmove(void *dst, void *src, int n);
int memcmp(void *src, void *dst, int n);
@@ -36,3 +38,8 @@
/* apm.s */
void apm(int id);
+
+/* uart.s */
+void uartinit(int p, int c);
+void uartputc(int p, int c);
+int uartgetc(int p);
--- a/sys/src/boot/pc/l.s
+++ b/sys/src/boot/pc/l.s
@@ -121,26 +121,20 @@
_halt:
JMP _halt
-TEXT getc(SB), $0
+TEXT kbdgetc(SB), $0
CALL rmode16(SB)
STI
- MOVB $0x00, AH
- BIOSCALL(0x16)
-_getcret:
- CALL16(pmode32(SB))
- ANDL $0xFF, AX
- RET
-
-TEXT gotc(SB), $0
- CALL rmode16(SB)
- STI
MOVB $0x01, AH
BIOSCALL(0x16)
- JNZ _getcret
+ JNZ _gotkey
CLR(rAX)
- JMP _getcret
+ JMP _pret32
+_gotkey:
+ CLR(rAX)
+ BIOSCALL(0x16)
+ JMP _pret32
-TEXT putc(SB), $0
+TEXT cgaputc(SB), $0
MOVL 4(SP),AX
CALL rmode16(SB)
STI
--- a/sys/src/boot/pc/mkfile
+++ b/sys/src/boot/pc/mkfile
@@ -36,7 +36,7 @@
$LD -o $target -H3 -T0x0800 -l $prereq
ls -l $target
-9boot&: l%.$O %.$O sub.$O apm.$O e820.$O a20.$O
+9boot&: l%.$O %.$O sub.$O apm.$O e820.$O a20.$O uart.$O
$LD -o $target -H3 -T0x7c00 -l $prereq
ls -l $target
--- a/sys/src/boot/pc/sub.c
+++ b/sys/src/boot/pc/sub.c
@@ -3,7 +3,38 @@
#include "fns.h"
#include "mem.h"
+int uart = -1;
+
void
+putc(int c)
+{+ cgaputc(c);
+ if(uart != -1)
+ uartputc(uart, c);
+}
+
+void
+print(char *s)
+{+ while(*s != 0){+ if(*s == '\n')
+ putc('\r');+ putc(*s++);
+ }
+}
+
+int
+getc(void)
+{+ int c;
+
+ c = kbdgetc();
+ if(c == 0 && uart != -1)
+ c = uartgetc(uart);
+ return c & 0x7f;
+}
+
+void
memset(void *dst, int v, int n)
{uchar *d = dst;
@@ -68,16 +99,6 @@
return nil;
}
-void
-print(char *s)
-{- while(*s != 0){- if(*s == '\n')
- putc('\r');- putc(*s++);
- }
-}
-
int
readn(void *f, void *data, int len)
{@@ -112,7 +133,9 @@
putc('>'); for(;;){ if(f == nil){- putc(*p = getc());
+ while((*p = getc()) == 0)
+ ;
+ putc(*p);
if(*p == '\r')
putc('\n'); else if(*p == '\b' && p > buf){@@ -147,7 +170,7 @@
timeout(int ms)
{ while(ms > 0){- if(gotc())
+ if(getc() != 0)
return 1;
usleep(100000);
ms -= 100;
@@ -164,6 +187,7 @@
static void apmconf(int);
static void e820conf(void);
+static void uartconf(char*);
static char*
getconf(char *s, char *buf)
@@ -261,9 +285,11 @@
*p++ = 0;
delconf(line);
if(memcmp("apm", line, 3) == 0){- apmconf('0' - line[3]);+ apmconf(line[3] - '0');
continue;
}
+ if(memcmp("console", line, 8) == 0)+ uartconf(p);
s = confend;
memmove(confend, line, n = strlen(line)); confend += n;
@@ -390,6 +416,16 @@
*confend = 0;
print(s);
+}
+
+static void
+uartconf(char *s)
+{+ if(*s >= '0' && *s <= '3'){+ uart = *s - '0';
+ uartinit(uart, (7<<5) | 3); /* b9660 l8 s1 */
+ } else
+ uart = -1;
}
static ulong
--- /dev/null
+++ b/sys/src/boot/pc/uart.s
@@ -1,0 +1,35 @@
+#include "x16.h"
+
+TEXT uartinit(SB), $0
+ MOVL c+8(SP), AX
+ MOVB $0x00, AH
+ JMP _uartbios
+
+TEXT uartputc(SB), $0
+ MOVL c+8(SP), AX
+ MOVB $0x01, AH
+ JMP _uartbios
+
+TEXT uartgetc(SB), $0
+ MOVL p+4(SP), DX
+ CALL rmode16(SB)
+ STI
+ MOVB $0x03, AH
+ BIOSCALL(0x14)
+ CALL16(pmode32(SB))
+ ANDL $0x8100, AX
+ MOVL $0x0100, BX
+ CMPL BX, AX
+ JE _uartread
+ XORL AX, AX
+ RET
+_uartread:
+ MOVB $0x02, AH
+_uartbios:
+ MOVL p+4(SP), DX
+ CALL rmode16(SB)
+ STI
+ BIOSCALL(0x14)
+ CALL16(pmode32(SB))
+ ANDL $0xFF, AX
+ RET
--
⑨