git: 9front

Download patch

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
--