summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-05-11 22:12:08 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-05-11 22:12:08 +0200
commite382b70880fe82176a086f909a027a2f85a884b6 (patch)
treebb78d2fdf655d17de59000db7eea4c6bcad2ca29
parent30596991abc9e452fbad8372f1ddcce12b87ce72 (diff)
downloadabaos-e382b70880fe82176a086f909a027a2f85a884b6.tar.gz
abaos-e382b70880fe82176a086f909a027a2f85a884b6.tar.bz2
added strlcpy (and a host test for it)
started to add I/O port code for VGA data and select ports
-rw-r--r--src/Makefile2
-rw-r--r--src/kernel.c2
-rw-r--r--src/port.asm25
-rw-r--r--src/port.c11
-rw-r--r--src/port.h9
-rw-r--r--src/stdlib.c7
-rw-r--r--src/stdlib.h6
-rw-r--r--src/string.c30
-rw-r--r--src/string.h2
-rw-r--r--src/vga.c28
-rw-r--r--src/vga.h6
-rw-r--r--tests/Makefile23
-rw-r--r--tests/test_strlcpy.c15
13 files changed, 165 insertions, 1 deletions
diff --git a/src/Makefile b/src/Makefile
index 4e0755a..45db0f7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -44,7 +44,7 @@ stdlib.o: stdlib.c
$(CC) $(CFLAGS) -c -o stdlib.o stdlib.c
clean:
- -rm -f boot.bin kernel.bin image.bin magic.bin *.o
+ -rm -f boot.bin kernel.bin image.bin magic.bin *.o kernel.map image.tmp
run-qemu: image.bin
qemu-system-i386 -m 32 -drive "file=image.bin,if=ide,format=raw"
diff --git a/src/kernel.c b/src/kernel.c
index a18e2d2..0f09819 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -30,6 +30,8 @@ void entry( void )
}
vga_put_char_at( &vga, x_pos, y_pos, '.' );
vga_put_newline( &vga );
+
+ vga_put_hex( &vga, 4711 );
//~ vga_set_color( &vga, VGA_COLOR_WHITE );
//~ vga_set_background_color( &vga, VGA_COLOR_RED );
diff --git a/src/port.asm b/src/port.asm
new file mode 100644
index 0000000..34d1f78
--- /dev/null
+++ b/src/port.asm
@@ -0,0 +1,25 @@
+[bits 32]
+
+global port8_write
+
+port8_write:
+ mov edx, [ebp+16]
+ mov eax, (edx)
+; mov dx, [ebp+8]
+; out ax, dl
+ ret
+
+
+;~ void port8_init( port8_t *port, uint16_t number )
+
+
+
+;~ global _myfunc
+;~ _myfunc: push ebp
+ ;~ mov ebp,esp
+ ;~ sub esp,0x40 ; 64 bytes of local stack space
+ ;~ mov ebx,[ebp+8] ; first parameter to function
+ ;~ ; some more code
+ ;~ leave ; mov esp,ebp / pop ebp
+ ;~ ret
+ ; __asm__ volatile("outb %0, %1" : : "a" (_data), "Nd" (_port));
diff --git a/src/port.c b/src/port.c
new file mode 100644
index 0000000..1a55669
--- /dev/null
+++ b/src/port.c
@@ -0,0 +1,11 @@
+#include "port.h"
+
+void port8_init( port8_t *port, uint16_t number )
+{
+ port->number = number;
+}
+
+uint8_t port8_read( port8_t *port )
+{
+ return 0;
+}
diff --git a/src/port.h b/src/port.h
index a4621de..98f63fc 100644
--- a/src/port.h
+++ b/src/port.h
@@ -1,5 +1,14 @@
#ifndef PORT_H
#define PORT_H
+#include <stdint.h>
+
+typedef struct port8_t {
+ uint16_t number; // port number, e.g. 0x3d4 VGA index register
+} port8_t;
+
+void port8_init( port8_t *port, uint16_t number );
+void port8_write( port8_t *port, uint8_t data );
+uint8_t port8_read( port8_t *port );
#endif /* PORT_H */
diff --git a/src/stdlib.c b/src/stdlib.c
new file mode 100644
index 0000000..9a9425f
--- /dev/null
+++ b/src/stdlib.c
@@ -0,0 +1,7 @@
+#include "stdlib.h"
+
+char *itoa( int v, char *s, int base )
+{
+ //~ *s = '\0';
+ return s;
+}
diff --git a/src/stdlib.h b/src/stdlib.h
new file mode 100644
index 0000000..fc6e248
--- /dev/null
+++ b/src/stdlib.h
@@ -0,0 +1,6 @@
+#ifndef STDLIB_H
+#define STDLIB_H
+
+char *itoa( int v, char *s, int base );
+
+#endif /* STDLIB_H */
diff --git a/src/string.c b/src/string.c
index 6aa46ef..9be5e43 100644
--- a/src/string.c
+++ b/src/string.c
@@ -40,3 +40,33 @@ size_t strlen( const char *s )
return len;
}
+
+int strcmp( const char *s1, const char *s2 )
+{
+ while( *s1 && *s2 && *s1 == *s2 ) {
+ s1++;
+ s2++;
+ }
+
+ return *s1 - *s2;
+}
+
+size_t strlcpy( char *d, const char *s, size_t n )
+{
+ size_t len = 0;
+
+ while( len < n && s[len] ) {
+ d[len] = s[len];
+ len++;
+ }
+
+ while( s[len] ) {
+ len++;
+ }
+
+ if( len >= n ) {
+ d[n-1] = '\0';
+ }
+
+ return len;
+}
diff --git a/src/string.h b/src/string.h
index 5efd35a..c3e3145 100644
--- a/src/string.h
+++ b/src/string.h
@@ -6,5 +6,7 @@
void *memset( void *s, int c, size_t n );
void *memmove( void *d, const void *s, size_t n );
size_t strlen( const char *s );
+int strcmp( const char *s1, const char *s2 );
+size_t strlcpy( char *d, const char *s, size_t n );
#endif /* STRING_H */
diff --git a/src/vga.c b/src/vga.c
index 92114d3..0c344f7 100644
--- a/src/vga.c
+++ b/src/vga.c
@@ -3,6 +3,7 @@
#include <stdbool.h>
#include "string.h"
+#include "stdlib.h"
static bool params_ok( vga_t *vga, const int x, const int y );
static int calculate_offset( vga_t *vga );
@@ -17,6 +18,10 @@ void vga_init( vga_t *vga )
vga->res_y = VGA_DEFAULT_RES_Y;
vga->color = VGA_COLOR_DARK_GREY;
vga->background_color = VGA_COLOR_BLACK;
+
+ // set up ports
+ port8_init( &vga->crtc_index_port, 0x3d4 );
+ port8_init( &vga->crtc_data_port, 0x3d5 );
// TODO: get current position from VGA hardware
vga_set_cursor_from_hardware( vga );
@@ -41,12 +46,25 @@ void vga_set_cursor( vga_t *vga, const int x, const int y )
vga->cursor_x = x;
vga->cursor_y = y;
+
+ // TODO: have a silent mode where we don't update the cursor
+ vga_set_cursor_on_hardware( vga );
}
void vga_set_cursor_from_hardware( vga_t *vga )
{
}
+void vga_set_cursor_on_hardware( vga_t *vga )
+{
+ uint16_t hw_cursor_pos = vga->cursor_x + vga->cursor_y * vga->res_x;
+
+ port8_write( &vga->crtc_index_port, 15 );
+ port8_write( &vga->crtc_index_port, hw_cursor_pos & 0xff );
+ port8_write( &vga->crtc_index_port, 14 );
+ port8_write( &vga->crtc_index_port, hw_cursor_pos >> 8 );
+}
+
int vga_get_cursor_x( vga_t *vga )
{
return vga->cursor_x;
@@ -142,6 +160,16 @@ void vga_put_string( vga_t *vga, const char *s )
}
}
+void vga_put_hex( vga_t *vga, const uint32_t v )
+{
+ char buf[9];
+
+ strlcpy( buf, "0x", 9 );
+ vga_put_string( vga, (const char *)buf );
+ itoa( v, (char *)buf, 16 );
+ vga_put_string( vga, (const char *)buf );
+}
+
void vga_put_newline( vga_t *vga )
{
vga->cursor_x = 0;
diff --git a/src/vga.h b/src/vga.h
index 70f9d53..aabffab 100644
--- a/src/vga.h
+++ b/src/vga.h
@@ -1,6 +1,8 @@
#ifndef VGA_H
#define VGA_H
+#include "port.h"
+
enum {
VGA_DEFAULT_RES_X = 80,
VGA_DEFAULT_RES_Y = 25
@@ -32,12 +34,15 @@ typedef struct vga_t {
int cursor_y; // current cursor position Y
vga_color_t color;
vga_color_t background_color;
+ port8_t crtc_index_port;
+ port8_t crtc_data_port;
} vga_t;
void vga_init( vga_t *vga );
void vga_clear_screen( vga_t *vga );
void vga_set_cursor( vga_t *vga, const int x, const int y );
void vga_set_cursor_from_hardware( vga_t *vga );
+void vga_set_cursor_on_hardware( vga_t *vga );
int vga_get_cursor_x( vga_t *vga );
int vga_get_cursor_y( vga_t *vga );
void vga_set_color( vga_t *vga, const vga_color_t color );
@@ -46,6 +51,7 @@ void vga_put_char_at( vga_t *vga, const int x, const int y, const char c );
void vga_put_string_at( vga_t *vga, const int x, const int y, const char *s );
void vga_put_char( vga_t *vga, const char c );
void vga_put_string( vga_t *vga, const char *s );
+void vga_put_hex( vga_t *vga, const uint32_t v );
void vga_put_newline( vga_t *vga );
#endif /* VGA_H */
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..af20182
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,23 @@
+CC := gcc
+CFLAGS := -std=c99 -m32 -ffreestanding -O0 -g -Wall -Werror
+INCLUDES = -I../src
+LD := ld
+
+all: test
+
+test_strlcpy: test_strlcpy.o
+
+test_strlcpy: test_strlcpy.o ../src/string.o
+ $(CC) -o test_strlcpy test_strlcpy.o ../src/string.o
+
+test_strlcpy.o: test_strlcpy.c
+ $(CC) $(CFLAGS) $(INCLUDES) -c -o test_strlcpy.o test_strlcpy.c
+
+../src/string.o: ../src/string.c
+ $(CC) $(CFLAGS) -c -o ../src/string.o ../src/string.c
+
+test: test_strlcpy
+ ./test_strlcpy
+
+clean:
+ -rm -f test_strlcpy *.o
diff --git a/tests/test_strlcpy.c b/tests/test_strlcpy.c
new file mode 100644
index 0000000..a23a5bc
--- /dev/null
+++ b/tests/test_strlcpy.c
@@ -0,0 +1,15 @@
+#include "string.h"
+
+int main( void )
+{
+ char *s = "test_string";
+ char d[8];
+ size_t n;
+
+ // copy into too small string
+ n = strlcpy( d, s, 4 );
+ if( n != 11 ) return 1;
+ if( strcmp( d, "tes" ) ) return 1;
+
+ return 0;
+}