How do i fix my newline procedure?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

How do i fix my newline procedure?

Post by NunoLava1998 »

I tried to add the support of newlines to my OS. I booted it using QEMU, and i got this result:
Image

I see that the newlines were indeed created, but the text ignored it, and got overlapped by a lot of things too.
Where i put \n in the text is Image for some reason (When i try to do I/O operations, i also get this character and a solid halt).

How do i fix this?

My terminal_putchar() is as follows:

Code: Select all

void terminal_putchar(char c) {
	terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
	if (++terminal_column == VGA_WIDTH) {
		terminal_column = 0;
		if (++terminal_row == VGA_HEIGHT)
			terminal_row = 0;
	}
	if (c == '\n') {
		terminal_row = terminal_row++;
		terminal_column = 0;
	}
}
Why is this happening, do i need to put the additional code somewhere else in terminal_putchar()? How can i fix this?
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: How do i fix my newline procedure?

Post by Ycep »

terminal_row = terminal_row++;
Do not use code that you do not understand.
You could use:

Code: Select all

terminal_row++;
or

Code: Select all

terminal_row=++terminal_row;
Really, learn C before trying to create operating system.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: How do i fix my newline procedure?

Post by NunoLava1998 »

Lukand wrote:
terminal_row = terminal_row++;
Do not use code that you do not understand.
You could use:

Code: Select all

terminal_row++;
or

Code: Select all

terminal_row=++terminal_row;
Really, learn C before trying to create operating system.
Removed the "possibly undefined" warning and now i got newlines. Except...
Image
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do i fix my newline procedure?

Post by iansjack »

You told it to print the newline character on the screen, and it did. What did you expect?
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: How do i fix my newline procedure?

Post by NunoLava1998 »

iansjack wrote:You told it to print the newline character on the screen, and it did. What did you expect?
It is succesful, but the Image shouldn't appear. I never put that there, i still need to know how to get rid of it.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How do i fix my newline procedure?

Post by Schol-R-LEA »

To clarify iansjack's comment: the actual 'newline character' - which isn't necessarily a single character, BTW - isn't a displayable character in the normal sense. You need to check for that character (or character sequence, depending on how you choose to represent newlines) and any other control characters such as tabs or the BEL character, before you write to the text video buffer, and handle them without actually putting the byte value into the buffer.

The reason I say that the newline isn't necessarily one character is because in the original ASCII character set, carriage return (the ASCII escape code called CR and with the value 0x0D, returning the writing head on the teletype to the zero column) and line feed (LF, 0x0A, advancing the paper roller by one line) were two separate operations. Note that these were explicitly defined in terms of controlling a teletype writing to a scroll of paper - this would come back to haunt everyone as the technology changed, as it meant that when CRT terminals and eventually graphical displays were developed, teletypes still had to be supported as a sort of lowest common denominator, meaning that if you wanted to write a program that worked everywhere, you couldn't make any assumptions about how the display worked.

Anyway, the 'standard' approach for a newline was to use a CR followed by a LF, which modeled the standard teletype mode. However, not every OS followed this. Unix, in particular, use a single LF as the newline character, while older Macintosh systems used a single CR. MS-DOS and Windows use the CR/LF sequence, in that order, and reversing them can cause some Windows programs to go haywire.

The practical upshot is that you will need to choose how you want to represent the newline.

Worse, these are control codes, which means you don't want to actually put them into the display buffer as there are no displayable glyphs for them - at least not standardized ones. The IBM console video buffer will treat those characters as representing glyphs, but the one it uses depend on the display page (the list of character glyphs used for a given character set), and in any case the character 'really is' a command rather than something you would display.

BTW, what do you expect the code snippet:

Code: Select all

      if (++terminal_row == VGA_HEIGHT)
         terminal_row = 0;
to do, and where will the cursor end up? What will the screen look like after the next character is displayed? What will be in the video buffer, and what will happen to the glyphs already being displayed?

As a final note, I would recommend defining a struct to represent the console state, rather than having separate terminal_row and terminal_column variables, if only because you will eventually have to handle different display modes and multiple virtual consoles. Something like this would be a start:

Code: Select all

struct TTY_CONSOLE 
{
    struct TEXT_VBUFFER *buffer;
    TEXT_VMODE mode;
    uint8_t row, column;
};
The implementation of the TEXT_VBUFFER struct, the TEXT_VMODE typedef, and the functions to operate on this struct, are left as an exercise :P
Last edited by Schol-R-LEA on Tue Dec 06, 2016 6:20 am, edited 5 times in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: How do i fix my newline procedure?

Post by osdever »

iansjack wrote:You told it to print the newline character on the screen, and it did. What did you expect?
+1

Nuno, your code does exactly what it should do. What's the problem?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: How do i fix my newline procedure?

Post by osdever »

Schol-R-LEA, thanks for last part of the post. I'll implement this now.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do i fix my newline procedure?

Post by iansjack »

NunoLava1998 wrote:the Image shouldn't appear. I never put that there
Oh yes, you did.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: How do i fix my newline procedure?

Post by osdever »

Nuno, your code first prints the character and only then checks for '\n', so it tries to print character corresponding to LF anyway.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How do i fix my newline procedure?

Post by Schol-R-LEA »

If we seem a bit flippant here, it is because these bugs are like old, familiar friends, and making these mistakes is a rite of passage for almost any OS developer. We can see the order of events coming well in advance because we've all been there ourselves.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: How do i fix my newline procedure?

Post by NunoLava1998 »

Schol-R-LEA wrote:To clarify iansjack's comment: the actual 'newline character' - which isn't necessarily a single character, BTW - isn't a displayable character in the normal sense. You need to check for that character (or character sequence, depending on how you choose to represent newlines) and any other control characters such as tabs or the BEL character, before you write to the text video buffer, and handle them without actually putting the byte value into the buffer.

The reason I say that the newline isn't necessarily one character is because in the original ASCII character set, carriage return (the ASCII escape code called CR and with the value 0x0D, returning the writing head on the teletype to the zero column) and line feed (LF, 0x0A, advancing the paper roller by one line) were two separate operations. Note that these were explicitly defined in terms of controlling a teletype writing to a scroll of paper - this would come back to haunt everyone as the technology changed, as it meant that when CRT terminals and eventually graphical displays were developed, teletypes still had to be supported as a sort of lowest common denominator, meaning that if you wanted to write a program that worked everywhere, you couldn't make any assumptions about how the display worked.

Anyway, the 'standard' approach for a newline was to use a CR followed by a LF, which modeled the standard teletype mode. However, not every OS followed this. Unix, in particular, use a single LF as the newline character, while older Macintosh systems used a single CR. MS-DOS and Windows use the CR/LF sequence, in that order, and reversing them can cause some Windows programs to go haywire.

The practical upshot is that you will need to choose how you want to represent the newline.

Worse, these are control codes, which means you don't want to actually put them into the display buffer as there are no displayable glyphs for them - at least not standardized ones. The IBM console video buffer will treat those characters as representing glyphs, but the one it uses depend on the display page (the list of character glyphs used for a given character set), and in any case the character 'really is' a command rather than something you would display.

BTW, what do you expect the code snippet:

Code: Select all

      if (++terminal_row == VGA_HEIGHT)
         terminal_row = 0;
to do, and where will the cursor end up? What will the screen look like after the next character is displayed? What will be in the video buffer, and what will happen to the glyphs already being displayed?

As a final note, I would recommend defining a struct to represent the console state, rather than having separate terminal_row and terminal_column variables, if only because you will eventually have to handle different display modes and multiple virtual consoles. Something like this would be a start:

Code: Select all

struct TTY_CONSOLE 
{
    struct TEXT_VBUFFER *buffer;
    TEXT_VMODE mode;
    uint8_t row, column;
};
The implementation of the TEXT_VBUFFER struct, the TEXT_VMODE typedef, and the functions to operate on this struct, are left as an exercise :P
BTW, what do you expect the code snippet:

Code: Select all

      if (++terminal_row == VGA_HEIGHT)
         terminal_row = 0;
to do, and where will the cursor end up? What will the screen look like after the next character is displayed? What will be in the video buffer, and what will happen to the glyphs already being displayed?
in a more human-favorable sense (i hope you know what i mean by that):

1: "if the variable terminal_row incremented equals the variable VGA_HEIGHT (25), set terminal_row to 0."
2: in the beginning of the line you just were in
3: the same but the first character is overwritten by what we tried to write
4: depends but the first should be different than what you wrote without the last character
5: nothing unless it gets overwritten

What i'm trying to achieve now is do newlines succesfully.

"oh yes, you did put that in"

Code: Select all

	/* Newline support is left as an exercise. */
	terminal_writestring("C mode succesful.\nThis should be a newline.\n");

	terminal_writestring("So there IS a newline after that text.\n Normal. Wait, new\n line?");
}
I want to see where's Image there. No, not trying to be mean or judge you or offend you.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: How do i fix my newline procedure?

Post by Octocontrabass »

NunoLava1998 wrote:I want to see where's Image there.
What is the ASCII value for '\n'? Which glyph has that value in code page 437?

It's not a coincidence that every time you put '\n' you get ◙.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: How do i fix my newline procedure?

Post by NunoLava1998 »

Octocontrabass wrote:
NunoLava1998 wrote:I want to see where's Image there.
What is the ASCII value for '\n'? Which glyph has that value in code page 437?

It's not a coincidence that every time you put '\n' you get ◙.
But how do i hide that? It's just that i need to make newlines that are succesful (and not with glyphs or failing to do a instruction)
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How do i fix my newline procedure?

Post by iansjack »

Are you seriously asking how you don't display a character if you don't want it to appear? Just don't display it!
Post Reply