How do I break the line and create a small wrapper?
-
- Posts: 1
- Joined: Fri Nov 06, 2020 4:20 am
- Libera.chat IRC: epicmouse
How do I break the line and create a small wrapper?
Hello, according to the official documentation, I compiled everything I needed, created a test kernel, launched it, but apparently it was planned that \ n would work as a line break, but it does not work. (https://wiki.osdev.org/Bare_Bones) Can someone explain how to break a line to C? And if possible, how to read text from the keyboard and enter it into a line? for example, a user entered a test, and I want to compare it with other commands, how can this be implemented? I'm just a newbie to C, but I used to write kernels a bit in assembly language.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How do I break the line and create a small wrapper?
You have to write that code yourself. There's an explanation in this section that should help.TheReactiveMouse wrote:Hello, according to the official documentation, I compiled everything I needed, created a test kernel, launched it, but apparently it was planned that \ n would work as a line break, but it does not work.
Write a keyboard driver.TheReactiveMouse wrote:And if possible, how to read text from the keyboard and enter it into a line?
We recommend being very familiar with the language you choose to write your OS. You might want to get some practice writing user-level programs in C before you continue.TheReactiveMouse wrote:I'm just a newbie to C, but I used to write kernels a bit in assembly language.
Re: How do I break the line and create a small wrapper?
Are you asking how to implement a command parser? This a moderately complex excercise, you will need to become more familiar with C and also have implemented the string functions before you can do this.TheReactiveMouse wrote:for example, a user entered a test, and I want to compare it with other commands, how can this be implemented?
What kernel models have you followed in the past? What paradigm do you plan to implement this time? What assembly ISAs are you familiar with?I'm just a newbie to C, but I used to write kernels a bit in assembly language.
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
Discord:https://discord.gg/zn2vV2Su
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: How do I break the line and create a small wrapper?
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:
Note that, in memory, this is all one big block, like so:
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.
Or rather,
If you write there again, with (say) 'e', it will overwrite the 'H', which probably isn't what you want.
Thus, to write 'e' as the second character of a word, you would have to write to the next position in the buffer.
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!",
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)
(ignoring what was a space in the original) to writing the 'W' at (1,0):
Now keep in mind that in the text buffer, this is actually
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
while at the text buffer level, it is actually
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.
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
|.........................|
|.........................|
|.........................|
|.........................|
Code: Select all
|....................................................................................................|
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........................|
|.........................|
|.........................|
|.........................|
Code: Select all
|H...................................................................................................|
Code: Select all
|e........................|
|.........................|
|.........................|
|.........................|
Code: Select all
|He.......................|
|.........................|
|.........................|
|.........................|
Code: Select all
|Hello,.World!............|
|.........................|
|.........................|
|.........................|
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,...................|
|.........................|
|.........................|
|.........................|
Code: Select all
|Hello,...................|
|W........................|
|.........................|
|.........................|
Code: Select all
|Hello,...................W..........................................................................|
The final results on the screen is
Code: Select all
|Hello,...................|
|World!...................|
|.........................|
|.........................|
Code: Select all
|Hello,...................World!.....................................................................|
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.
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.
Re: How do I break the line and create a small wrapper?
That looks like a really good explanation to me, Schol-R-LEA! But it's possible I'm biased because I already 'get' this 2D-layout stuff. I do think diagrams are always good, at any rate. I've just got a little simplification...
DOS and maybe BIOS write-to-screen routines do it this way. I once found ASCII-art files with reversed newline sequences; the line feed first. They worked fine under DOS because it handles each character separately. Common terminal emulators in Unixes also do this, but it's a bit harder to see because Unix "TTY" drivers have different modes. Sometimes you see it when a program which had the terminal in raw mode crashes. Then, simple programs which need cooked mode send Unix newlines - actually LF - and the cursor just goes down a line without changing column.
Handling the CR LF pair needn't be hard in the terminal driver. The pair is well-suited for teletypewriters - things from the 1950s and 60s which were barely more than mechanical typewriters at all. Just like those teletypewriters, you can handle them separately with good results. "Carriage return" should send the cursor to the beginning of the line: just zero the cursor's column number. "Line feed" should simply send the cursor to the next line; increment the cursor's line number.Schol-R-LEA wrote: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.
DOS and maybe BIOS write-to-screen routines do it this way. I once found ASCII-art files with reversed newline sequences; the line feed first. They worked fine under DOS because it handles each character separately. Common terminal emulators in Unixes also do this, but it's a bit harder to see because Unix "TTY" drivers have different modes. Sometimes you see it when a program which had the terminal in raw mode crashes. Then, simple programs which need cooked mode send Unix newlines - actually LF - and the cursor just goes down a line without changing column.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: How do I break the line and create a small wrapper?
Since you are a newbie, let me explain this to you a bit more clearly.
Assuming you are using VGA text mode, then your terminal is 80x25.
In your terminal driver you should have a variable for your current column and current row.
When you go to put_entry_at, you multiply the current row by the height of your terminal (25) and then add the current column to get the index of the character position.
Typically, the put_char function manages the incrementing of columns and rows.
When you are in the put_char function, have a conditional that checks if the character is '\n', and if it is, set the current column to 0 and increment the current row.
Now you have a line break.
Assuming you are using VGA text mode, then your terminal is 80x25.
In your terminal driver you should have a variable for your current column and current row.
When you go to put_entry_at, you multiply the current row by the height of your terminal (25) and then add the current column to get the index of the character position.
Typically, the put_char function manages the incrementing of columns and rows.
When you are in the put_char function, have a conditional that checks if the character is '\n', and if it is, set the current column to 0 and increment the current row.
Now you have a line break.
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: How do I break the line and create a small wrapper?
Nice and simple indeed, but there are 2 little mistakes in this line.rizxt wrote:When you go to put_entry_at, you multiply the current row by the height of your terminal (25) and then add the current column to get the index of the character position.
1: You have to multiply the current row by the width of the terminal, 80.
2: The VGA text memory locations go char, attr, char, attr, char, attr, etc., so you're not quite done yet; you have to multiply by 2 to get the character position. The attributes should all be set to light gray on black by the boot process, so you can safely ignore them until you're ready for them. Just be sure not to touch the attribute bytes by mistake, or your characters could end up black-on-black.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie