[SOS] [PATCH] printk et scrolling ecran

Christophe Lucas c.lucas at ifrance.com
Sam 21 Aou 20:20:02 CEST 2004


Salut,

Voici un petit patch pour afficher un peu plus aisément à l'écran.
Cette fonction gère le scrolling à l'écran.

Bon samedi.

-- 
Amicalement/Regards
Christophe

-----------------------------------------------------------------
Christophe Lucas <c.lucas at ifrance.com>         developer/sysadmin
Registered User #271267              http://odie.mcom.fr/~clucas/
RotomaLUG member (http://www.rotomalug.org)   gpg dsa: 0x1E87C874
-----------------------------------------------------------------

Le carré de l'hypoténuse parlementaire est égal à la somme de 
l'imbécilité construite sur ses deux côtés extrêmes.
	-+- Pierre Dac -+-
-------------- section suivante --------------
diff -urbNB sos-a2-vanilla/drivers/x86_videomem.c sos-a2/drivers/x86_videomem.c
--- sos-a2-vanilla/drivers/x86_videomem.c	2004-06-28 10:28:02.000000000 +0200
+++ sos-a2/drivers/x86_videomem.c	2004-08-21 19:58:24.000000000 +0200
@@ -19,18 +19,23 @@
 #include <sos/klibc.h>
 #include <hwcore/ioports.h>
 
+#include "bochs.h"
+
 #include "x86_videomem.h"
 
 /* The text video memory starts at address 0xB8000. Odd bytes are the
    ASCII value of the character, even bytes are attribute for the
    preceding character. */
-#define VIDEO   0xb8000
 
+#define VIDEO   	0xb8000
+#define VIDEO_SIZE	0x01f40	/* 80*25*2*2 == 8000 */
+#define VIDEO_END	0xb9f40
 
 /* Console screen size */
 #define LINES   25
 #define COLUMNS 80
 
+static unsigned char	currentX, currentY, currentAttribute ;
 
 /** The structure of a character element in the video memory. @see
     http://webster.cs.ucr.edu/AoA DOS edition chapter 23 */
@@ -53,6 +58,11 @@
 #define CRT_REG_INDEX 0x3d4
 #define CRT_REG_DATA  0x3d5
 
+	currentX = 0 ;
+	/* Pour la ligne du haut montrant interruptions et exceptions */
+	currentY = 1 ;
+	currentAttribute = SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE ; 
+
   /* CRT index port => ask for access to register 0xa ("cursor
      start") */
   outb(0x0a, CRT_REG_INDEX);
@@ -68,8 +78,7 @@
 {
   /* Clears the screen */
   int i;
-  for(i = 0 ; i < LINES*COLUMNS ; i++)
-    {
+  	for(i = 0 ; i < LINES*COLUMNS ; i++) {
       (*video)[i].character = 0;
       (*video)[i].attribute = attribute;
     }
@@ -96,6 +104,37 @@
   return SOS_OK;
 }
 
+sos_ret_t printk_putstring( const char *str )
+{
+    unsigned video_offs, video_offs_base ;
+
+    video_offs = currentY * COLUMNS + currentX ;
+    if( video_offs >= LINES*COLUMNS) {
+	unsigned offset, size ;
+		
+	size = strlen( str ) ;
+	offset = size / COLUMNS + 1 ;
+	scroll_screen( offset );
+    }
+  
+    video_offs = currentY * COLUMNS + currentX ;
+    video_offs_base = video_offs ;
+
+    for ( ; str && *str && (video_offs < LINES*COLUMNS) ; str++, video_offs++) {
+	if( (unsigned char)*str == '\n' ) {
+	    video_offs += COLUMNS - (video_offs - video_offs_base ) - currentX - 1  ;
+	} else {
+	    (*video)[video_offs].character = (unsigned char)*str;
+	    (*video)[video_offs].attribute = currentAttribute;
+	}
+    }
+
+    currentX = (video_offs - currentY*COLUMNS) % COLUMNS ;
+    currentY = video_offs/COLUMNS - currentX ;
+
+    return SOS_OK;
+}
+
 
 sos_ret_t sos_x86_videomem_putchar(unsigned char row, unsigned char col,
 				   unsigned char attribute,
@@ -126,3 +165,59 @@
   
   return sos_x86_videomem_putstring(row, col, attribute, buff);
 }
+
+sos_ret_t printk( const char *format, ... )
+{
+    char buff[256];
+    va_list ap;
+  
+    va_start(ap, format);
+    vsnprintf(buff, sizeof(buff), format, ap);
+    va_end(ap);
+	
+    return printk_putstring( buff );
+}
+
+unsigned char get_current_X_pos()
+{
+	return currentX ;
+}
+
+unsigned char get_current_Y_pos()
+{
+	return currentY ;
+}
+
+
+void scroll_screen( int nb_line )
+{
+    unsigned i, offset ;
+    
+    offset = LINES * COLUMNS - nb_line * 80 ;
+
+    for( i=0 ; i<LINES*COLUMNS ; i++ ) {
+	if( i < offset ) {
+	    (*video)[i].character = (*video)[i+nb_line*80].character ;
+	    (*video)[i].attribute = (*video)[i+nb_line*80].attribute ;
+	} else {
+	    (*video)[i].character = 0 ;
+	    (*video)[i].attribute = currentAttribute ;
+	}
+    }
+
+    print_bochs_coords();
+
+    if( currentY < nb_line ) {
+	currentY = 0 ;
+    } else {
+	currentY -= nb_line ;
+    }
+
+    print_bochs_coords();
+}
+
+void print_bochs_coords()
+{
+    sos_bochs_printf("currentX: %d - currentY: %d\n", currentX, currentY );
+}
+
diff -urbNB sos-a2-vanilla/drivers/x86_videomem.h sos-a2/drivers/x86_videomem.h
--- sos-a2-vanilla/drivers/x86_videomem.h	2004-06-28 10:28:02.000000000 +0200
+++ sos-a2/drivers/x86_videomem.h	2004-08-21 18:11:58.000000000 +0200
@@ -95,4 +95,12 @@
 				  const char *format, /* args */...)
      __attribute__ ((format (printf, 4, 5)));
 
+
+sos_ret_t printk( const char *format, ... )
+     __attribute__ ((format (printf, 1, 2)));
+
+void scroll_screen( int nb_line );
+void print_bochs_coords() ;
+
+
 #endif /* _SOS_X86_VIDEOMEM_H_ */
diff -urbNB sos-a2-vanilla/sos/main.c sos-a2/sos/main.c
--- sos-a2-vanilla/sos/main.c	2004-06-28 10:28:02.000000000 +0200
+++ sos-a2/sos/main.c	2004-08-21 19:52:01.000000000 +0200
@@ -24,11 +24,14 @@
 #include <hwcore/irq.h>
 #include <hwcore/exception.h>
 #include <hwcore/i8254.h>
 #include <sos/klibc.h>
 #include <sos/assert.h>
 #include <drivers/x86_videomem.h>
 #include <drivers/bochs.h>
 
+sos_ui32_t clock_count = 0;
 
 /* Helper function to display each bits of a 32bits integer on the
    screen as dark or light carrets */
@@ -54,8 +57,6 @@
 /* Clock IRQ handler */
 static void clk_it(int intid)
 {
   display_bits(0, 48,
 	       SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
 	       clock_count);
@@ -101,15 +101,18 @@
 			    (unsigned)mbi->mem_upper);
   else
     /* Not loaded with grub */
+  /*  sos_x86_videomem_printf(1, 0,
 			    SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
 			    "Welcome to SOS");
+ */
+	printk( "Welcome to SOS\n" );
 
   sos_bochs_putstring("Message in a bochs\n");
 
   /* Setup CPU segmentation and IRQ subsystem */
   sos_gdt_setup();
   sos_idt_setup();
+	printk( "GDT and IDT are setup: ok\n");
 
   /* Setup SOS IRQs and exceptions subsystem */
   sos_exceptions_setup();
@@ -117,16 +120,23 @@
 
   /* Configure the timer so as to raise the IRQ0 at a 100Hz rate */
   sos_i8254_set_frequency(100);
+  printk("i8254 configure à 100Hz.\n");
 
   /* Binding some HW interrupts and exceptions to software routines */
   sos_irq_set_routine(SOS_IRQ_TIMER,
 			    clk_it);
+  printk("Interruption timer (IRQ 0) captee.\n" );
+  
+  sos_irq_set_routine( SOS_IRQ_KEYBOARD , kbd_handler ) ;
+  printk("Interrution clavier (IRQ 1) captee.\n" );
+  
   sos_exception_set_routine(SOS_EXCEPT_DIVIDE_ERROR,
 			    divide_ex);
   /* Enabling the HW interrupts here, this will make the timer HW
      interrupt call our clk_it handler */
   asm volatile ("sti\n");
 
+	
   /* Raise a rafale of 'division by 0' exceptions. All this code is
      not really needed (equivalent to a bare "i=1/0;"), except when
      compiling with -O3: "i=1/0;" is considered dead code with gcc


Plus d'informations sur la liste de diffusion Sos