Have you read the pages mentioned in the
Links and Advice for Newcomers thread? While it isn't directly relevant here, it is will help you get an idea of the scope of OS dev.
And as others have said, OS dev really isn't the place to be learning C and assembly. You really need a solid understanding of both before beginning an OS project.
For the specific problem of newlines, this has come up in this forum
many,
many times before. See the pages on
Printing To Screen and the
Text Mode Cursor for full details. I'll go over the general idea here, though.
The thing to understand is that on the PC (and many other systems) the text mode video memory is a continuous block mapping to the whole screen, and that adding a new line actually means moving where you are inserting characters to a different part of that memory block - namely, the character cell which corresponds to the start of the next line.
Your typical 'text mode' string writing function will try to make this behave like an old-fashioned 'teletypewriter' instead, which had a literal typewriter printing to a scroll of paper in a fixed order, but that is an illusion to make printing to the screen easier.
For example, a blank video screen (4x25 in the example below) is actually filled with space characters, which I'll show here using periods to show where the blanks are:
Code: Select all
|.........................|
|.........................|
|.........................|
|.........................|
Note that, in memory, this is all one big block, like so:
Code: Select all
|....................................................................................................|
Note also that, on the PC, the text memory is made up of character/attribute pairs, so each character cell is actually two bytes of memory. This means that the text buffer is twice the size of the screen - for this 4x25 screen (100 characters), it is 200 bytes, and so forth.
It is up to you to know which if these character cells you are writing to at a given moment, which usually means you need an v,h pair (vertical and horizontal) to keep track of the position, what is known as a 'cursor'.
So let's say you have your cursor at (0,0), the first cell in the text buffer. You would write a character - let's say 'H' - to that position in memory.
Code: Select all
|H........................|
|.........................|
|.........................|
|.........................|
Or rather,
Code: Select all
|H...................................................................................................|
If you write there again, with (say) 'e', it will overwrite the 'H', which probably isn't what you want.
Code: Select all
|e........................|
|.........................|
|.........................|
|.........................|
Thus, to write 'e' as the second character of a word, you would have to write to the next position in the buffer.
Code: Select all
|He.......................|
|.........................|
|.........................|
|.........................|
In order to keep track of this, you would want to increment the
h coordinate for each character of you add. So after you insert the phrase "Hello, World!",
Code: Select all
|Hello,.World!............|
|.........................|
|.........................|
|.........................|
Your cursor would be (0,12).
But what if you want to write "Hello,\nWorld!", instead? Well, first off, your string writing routine would have to scan the string for the newline escape code, '\n', which is itself a bit complex since the C compiler automatically converts the substring "\n" to whatever your OS uses for the newline. The newline isn't necessarily a single character, I should add; in Unix it is a single 'line feed' character (ASCII 10), but in Windows is is the pair 'carriage return'/'line feed' (ASCII 13 followed immediately by ASCII 10). The
history behind this is a bit complicated, but for now just realize that a newline 'character' maybe not be just a single character in the string.
Once your function sees that newline in the string, rather than writing the character to memory, it needs to modify where you are writing to. In short, this means resetting the horizontal component of the cursor to 0, and incrementing the vertical component - in other words, you go from writing the ',' at (0,5)
Code: Select all
|Hello,...................|
|.........................|
|.........................|
|.........................|
(ignoring what was a space in the original) to writing the 'W' at (1,0):
Code: Select all
|Hello,...................|
|W........................|
|.........................|
|.........................|
Now keep in mind that in the text buffer, this is actually
Code: Select all
|Hello,...................W..........................................................................|
But since you aren't changing the trailing spaces on the 'first line', they just stay as they were.
The final results on the screen is
Code: Select all
|Hello,...................|
|World!...................|
|.........................|
|.........................|
while at the text buffer level, it is actually
Code: Select all
|Hello,...................World!.....................................................................|
I hope this has made it clearer what is actually going on, at least as far as the string writing functions and the text buffer are concerned.