[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