// in: char *text [The text to write to the screen.]
// out: Nothing.
void k_print( char *text ) {
static unsigned int line_number = 0;
static unsigned int column_number = 0;
char *video_memory = (char *) VIDEO_MEMORY;
while( *text != 0 ) {
if( *text == '\n' ) {
text++;
column_number = 0;
line_number++;
video_memory = (char *) ( VIDEO_MEMORY + ( line_number * SCREEN_WIDTH * 2 ) + ( column_number * 2 ) );
} else {
*video_memory = *text;
text++;
column_number++;
video_memory++;
*video_memory = WHITE_TEXT;
video_memory++;
}
}
}
🔒 Locked
Help with print function
Advertisement
Original Post
Ok, I have this function that prints text to the video buffer (0xB8000). However, I can't seem to figure out how to stack data on top of each other so that I can use the command as many times as I'd like without clearing the screen first :( Basically, what I want is I want to add a new line beneath a textstring when I use the command, so that when I use it again, the new text gets printed beneath the old one. Can anyone please help?
I would say that you need to append the new text to the old text in the buffer and then send the buffer to print again. In other words, you have to overwrite the earlier screen text, but since it's saved in the buffer, it gets written again just before the new text is written.
[source lang = "c"]void k_print( char *text ) {static unsigned int line_number = 0;static unsigned int column_number = 0;char *video_memory = (char *) VIDEO_MEMORY; while( *text != 0 ) { if( *text == '\n' ) { text++; column_number = 0; line_number++; video_memory = (char *) ( VIDEO_MEMORY + ( line_number * SCREEN_WIDTH * 2 ) + ( column_number * 2 ) ); } else { VIDEO_MEMORY = (char*) *video_memory; *video_memory = *text; text++; column_number++; video_memory++; *video_memory = WHITE_TEXT; video_memory++; } }}Like so? I have to reboot my machine to run this code, so I'd really like to know :) Thanks btw :)
Nevermind. Tried this:
But it still doesn't work :(
[source lang = "c"]// in: char *text [The text to write to the screen.]// out: Nothing.void k_print( char *text ) {static unsigned int line_number = 0;static unsigned int column_number = 0;char *video_memory = (char *) VIDEO_MEMORY; while( *text != 0 ) { if( *text == '\n' ) { text++; column_number = 0; line_number++; video_memory = (char *) ( VIDEO_MEMORY + ( line_number * SCREEN_WIDTH * 2 ) + ( column_number * 2 ) ); } else { VIDEO_MEMORY = (char*) *video_memory; *video_memory = *text; text++; column_number++; video_memory++; *video_memory = WHITE_TEXT; video_memory++; } }}But it still doesn't work :(
Wow, a question about text mode. Well, you have two options - when you want to scroll a line down you either have to copy all of the lines on the screen up one, or you can move the video base address down a line. The second one's probably considerably more work because you only have a certain number of video pages so eventually you have to have a way to get back to the start and modern computers are far too fast to be slowed down by moving 4kb or so of data. The second trick used to be used for VGA side scrolling games when computers weren't fast enough to redraw the entire screen, so you moved the video base address by one row/column and only had to redraw one row/column and the characters.
There is actually a third option if you're in real mode or can run vm86 mode (that's what it's called on Linux - I've forgotten the official name - it's emulated 16 bit mode) - you can call the BIOS and get it to do your text output for you. That might well be slow though.
What are you writing anyway, something for DOS or a toy OS?
There is actually a third option if you're in real mode or can run vm86 mode (that's what it's called on Linux - I've forgotten the official name - it's emulated 16 bit mode) - you can call the BIOS and get it to do your text output for you. That might well be slow though.
What are you writing anyway, something for DOS or a toy OS?
I'm writing a toy os :)
I'm not sure how to do what you said, but I've figured that if I could make an if statement to find the "\0" character, I could add a new line just like with the "\n" character. I tried writing "if (*text == '\0')", but that didn't work :( Any ideas?
I'm not sure how to do what you said, but I've figured that if I could make an if statement to find the "\0" character, I could add a new line just like with the "\n" character. I tried writing "if (*text == '\0')", but that didn't work :( Any ideas?
Off the top of my head:
The pointer arithmatic probably won't work without some adjustment but otherwise I think that's correct. I was messing about with this myself recently using GRUB for a bootloader to escape the really nasty bootstrap stuff (and QEMU for testing). I remember sorting out memory layout being pretty nasty.
void k_print(const char *text){ static unsigned line_no = 0, col_no = 0; static char *video_memory_ptr = VIDEO_MEMORY; int i; for (i = 0; text != '\0'; ++i) { if (text == '\n') { video_memory_ptr += (SCREEN_WIDTH - col_no)*2; line_no++; col_no = 0; } else { video_memory_ptr[0] = text; video_memory_ptr[1] = WHITE_TEXT; video_memory_ptr += 2; col_no++; if (col_no == SCREEN_WIDTH) { col_no = 0; line_no++; } } if (line_no == SCREEN_HEIGHT) { memmove(VIDEO_MEMORY, VIDEO_MEMORY + (SCREEN_HEIGHT*2), SCREEN_WIDTH*(SCREEN_HEIGHT-1)*2); line_no--; video_memory_ptr = VIDEO_MEMORY + SCREEN_WIDTH*(SCREEN_HEIGHT-1)*2; } }}The pointer arithmatic probably won't work without some adjustment but otherwise I think that's correct. I was messing about with this myself recently using GRUB for a bootloader to escape the really nasty bootstrap stuff (and QEMU for testing). I remember sorting out memory layout being pretty nasty.
Well, yeah. Since it's impossible to fit anything resembling a modern OS into one sector all the bootloaders I know of employ some kind of blindly loading more from a set sector on the disk with no regard to the file system. It's an ugly system and I for one will not be sorry to see the x86 architecture die (it's got more baggage than you could fit on a jumbo jet), and I think it's only got a few years left.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement