Got rid of columns and rows in VGA driver
This commit is contained in:
parent
2b13f87f62
commit
4fe70142f6
|
@ -36,7 +36,7 @@ operation the high bits are cancelled out. Neat huh?
|
|||
*/
|
||||
|
||||
#define LOW8(x) (u8)(x & 0xff)
|
||||
#define HIGH8(x) (u8)(x >> 8)
|
||||
#define HIGH8(x) (u8)(LOW8(x >> 8))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ load_kernel:
|
|||
; Loads the kernel into memory
|
||||
mov bx, kernel_offset
|
||||
mov cl, reserved_sectors + 1
|
||||
mov dh, 5
|
||||
mov dh, 3
|
||||
mov dl, [boot_drive]
|
||||
call load_disk
|
||||
mov si, kernel_loaded_msg
|
||||
|
|
|
@ -22,13 +22,9 @@ limitations under the License.
|
|||
#include <stdarg.h>
|
||||
|
||||
|
||||
u16 getCursorOffset(void);
|
||||
void setCursorOffset(u16 offset);
|
||||
u16 putchar(char ch, u8 row, u8 col, char attr);
|
||||
u16 getOffset(u8 row, u8 col);
|
||||
u8 getRow(u16 offset);
|
||||
u8 getColumn(u16 offset);
|
||||
void printc(char c);
|
||||
u32 getCursorOffset(void);
|
||||
void setCursorOffset(u32 offset);
|
||||
void putchar(char ch, char attr);
|
||||
|
||||
|
||||
|
||||
|
@ -39,21 +35,14 @@ void kprint(const char* message) {
|
|||
Prints a null-terminated string to the VGA
|
||||
text buffer
|
||||
*/
|
||||
i32 offset = getCursorOffset();
|
||||
i32 row = getRow(offset), col = getColumn(offset);
|
||||
while (*message) {
|
||||
offset = putchar(*(message++), row, col, 0);
|
||||
// We compute the new row and column for the
|
||||
// next iteration. Hopefully the compiler inlines
|
||||
// these two calls
|
||||
row = getRow(offset);
|
||||
col = getColumn(offset);
|
||||
putchar(*(message++), 0);
|
||||
}
|
||||
setCursorOffset(getOffset(row, col));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO
|
||||
void kprintf(const char *fmt, ...) {
|
||||
/*
|
||||
A simple reimplementation of printf in
|
||||
|
@ -69,13 +58,9 @@ void kprintf(const char *fmt, ...) {
|
|||
char* sbuf; /* Used to print strings */
|
||||
char ibuf[12]; /* Used as input to itoa. 12 is the number of
|
||||
digits of 2 ** 32 + 2 (for the sign and null byte)*/
|
||||
u32 offset = getCursorOffset();
|
||||
u32 row = getRow(offset), col = getColumn(offset);
|
||||
memset(ibuf, '0', 12);
|
||||
while (*fmt) {
|
||||
offset = putchar(*(fmt++), row, col, 0);
|
||||
row = getRow(offset);
|
||||
col = getColumn(offset);
|
||||
putchar(*(fmt++), 0);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -93,45 +78,28 @@ void inline kprintln(const char* message) {
|
|||
|
||||
// Private API below
|
||||
|
||||
u16 putchar(char ch, u8 row, u8 col, char attr) {
|
||||
void putchar(char ch, char attr) {
|
||||
/*
|
||||
Writes a single character to the VGA text buffer
|
||||
at the given row and column and returns the new
|
||||
location of the cursor. If the attr byte is zero,
|
||||
its value is the result of the expansion of the
|
||||
LIGHT_GREY_ON_BLACK macro. If both row and col
|
||||
are equal to -1, the cursor location is retrieved
|
||||
from the VGA controller using I/O ports. The following
|
||||
escape sequences are handled:
|
||||
If the attr byte is zero, its value is the result
|
||||
of the expansion of the LIGHT_GREY_ON_BLACK macro.
|
||||
|
||||
The following escape sequences are handled:
|
||||
- '\n' -> Goes to the next line
|
||||
- '\t' -> Prints VGA_TABSIZE spaces
|
||||
- '\r' -> Resets the cursor's column, but not the row
|
||||
Upon error, a negative value is returned; The possible
|
||||
errors are codes are
|
||||
- -1 -> Column out of bounds
|
||||
- -2 -> Row out of bounds
|
||||
- '\r' -> Goes to the beginning of the line
|
||||
*/
|
||||
|
||||
if (!attr) {
|
||||
// No color data provided? We supply our own
|
||||
attr = LIGHT_GREY_ON_BLACK;
|
||||
}
|
||||
if (col >= MAX_COLS) {
|
||||
return -1;
|
||||
}
|
||||
if (row >= MAX_ROWS) {
|
||||
return -2;
|
||||
}
|
||||
u16 offset = getOffset(row, col);
|
||||
u32 offset = getCursorOffset();
|
||||
switch (ch) {
|
||||
// Note the difference between a carriage return (which
|
||||
// only brings the write head back at 0 without changing
|
||||
// the row) and the newline (which increases the row as well)
|
||||
case '\r':
|
||||
offset = getOffset(getRow(offset), 0);
|
||||
offset -= offset % MAX_COLS;
|
||||
break;
|
||||
case '\n':
|
||||
offset = getOffset(getRow(offset) + 1, 0);
|
||||
offset += MAX_COLS - offset % MAX_COLS;
|
||||
break;
|
||||
case '\t':
|
||||
for (i32 i = 0; i < VGA_TABSIZE; i++) {
|
||||
|
@ -146,6 +114,7 @@ u16 putchar(char ch, u8 row, u8 col, char attr) {
|
|||
offset += 2;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
// We check if we reached the end of the screen, in which
|
||||
// case we scroll
|
||||
if (offset >= SCREEN_SIZE * 2) {
|
||||
|
@ -165,12 +134,13 @@ u16 putchar(char ch, u8 row, u8 col, char attr) {
|
|||
|
||||
offset -= 2 * MAX_COLS;
|
||||
}
|
||||
*/
|
||||
setCursorOffset(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
u16 getCursorOffset(void) {
|
||||
u32 getCursorOffset(void) {
|
||||
/*
|
||||
Returns the current offset of
|
||||
the VGA text cursor
|
||||
|
@ -183,22 +153,17 @@ u16 getCursorOffset(void) {
|
|||
// Memory-mapped I/O is great, isn't it?
|
||||
writeByte(REG_SCREEN_CTRL, 14);
|
||||
// And we read it
|
||||
u16 offset = readByte(REG_SCREEN_DATA);
|
||||
// Since we requested the high byte
|
||||
// (i.e. the 8 most significant bits)
|
||||
// we now want to move them up by 8 places.
|
||||
// Conveniently, that's exactly what a
|
||||
// left shift is for :)
|
||||
u32 offset = readByte(REG_SCREEN_DATA);
|
||||
offset <<= 8;
|
||||
// Now we request the low byte of the cursor
|
||||
// position
|
||||
writeByte(REG_SCREEN_CTRL, 15);
|
||||
offset += readByte(REG_SCREEN_DATA);
|
||||
return offset * 2; // Times 2 because VGA cells are 2 bytes long
|
||||
return offset * 2; // Times 2 because VGA cells are 2 bytes long
|
||||
}
|
||||
|
||||
|
||||
void setCursorOffset(u16 offset) {
|
||||
void setCursorOffset(u32 offset) {
|
||||
/*
|
||||
Sets the offset of the VGA text
|
||||
cursor to the desired value. Note
|
||||
|
@ -229,48 +194,13 @@ void setCursorOffset(u16 offset) {
|
|||
void clearScreen(void) {
|
||||
/*
|
||||
Clears the screen and resets
|
||||
the cursor position to 0, 0
|
||||
the cursor position to 0
|
||||
*/
|
||||
for (i32 i = 0; i < SCREEN_SIZE; i++) {
|
||||
VMEM_BUF[i * 2] = ' '; // The screen is actually never "empty", just filled with spaces
|
||||
VMEM_BUF[i * 2 + 1] = LIGHT_GREY_ON_BLACK;
|
||||
}
|
||||
setCursorOffset(getOffset(0, 0));
|
||||
setCursorOffset(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
u16 inline getOffset(u8 row, u8 col) {
|
||||
/*
|
||||
Converts a column, row pair into
|
||||
an absolute offset into the VGA
|
||||
text buffer
|
||||
*/
|
||||
|
||||
// We multiply by 2 because each VGA
|
||||
// character cell is 2 bytes long
|
||||
return (row * MAX_COLS + col) * 2;
|
||||
}
|
||||
|
||||
|
||||
u8 inline getRow(u16 offset) {
|
||||
|
||||
/*
|
||||
Converts an absolute offset into
|
||||
the VGA text buffer into a row
|
||||
*/
|
||||
|
||||
// Conversely, we divide by two
|
||||
// when converting back from the
|
||||
// raw offset to columns/rows
|
||||
return offset / (2 * MAX_COLS);
|
||||
}
|
||||
|
||||
|
||||
u8 inline getColumn(u16 offset) {
|
||||
/*
|
||||
Converts an absolute offset into
|
||||
the VGA text buffer into a column
|
||||
*/
|
||||
return (offset - (getRow(offset) * 2 * MAX_COLS)) / 2;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue