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