diff --git a/.vscode/settings.json b/.vscode/settings.json index 6f2e1e8..feb886d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "files.associations": { - "ktypes.h": "c" + "ktypes.h": "c", + "ports.h": "c" } } \ No newline at end of file diff --git a/Makefile b/Makefile index f04c4bb..03f42ae 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ BUILD_PATHS += $(subst src/,$(OBJDIR),$(dir $(DRIVERS_OBJS))) prepare: - mkdir -p $(BUILD_PATHS) + mkdir -p $(BUILD_PATHS) build obj dist clean: diff --git a/include/kernel/drivers/ports/ports.h b/include/kernel/drivers/ports/ports.h index 9c41ad0..611f38b 100644 --- a/include/kernel/drivers/ports/ports.h +++ b/include/kernel/drivers/ports/ports.h @@ -18,7 +18,7 @@ limitations under the License. #define TSOS_DRV_PORTS_H -#include "kernel/ktypes.h" +#include "kernel/types.h" byte readByte(u16 port); diff --git a/include/kernel/drivers/vga/screen.h b/include/kernel/drivers/vga/screen.h index d673555..8f7b4f8 100644 --- a/include/kernel/drivers/vga/screen.h +++ b/include/kernel/drivers/vga/screen.h @@ -18,7 +18,7 @@ limitations under the License. #ifndef TSOS_DRV_VGA_SCREEN #define TSOS_DRV_VGA_SCREEN -#include "kernel/ktypes.h" +#include "kernel/types.h" #include "kernel/drivers/ports/ports.h" diff --git a/include/kernel/ktypes.h b/include/kernel/types.h similarity index 92% rename from include/kernel/ktypes.h rename to include/kernel/types.h index 00c9b7a..2fbf3a5 100644 --- a/include/kernel/ktypes.h +++ b/include/kernel/types.h @@ -19,12 +19,14 @@ limitations under the License. #ifndef TSOS_KTYPES #define TSOS_KTYPES +#define true 1 +#define false 0 typedef unsigned char byte; typedef unsigned short int u16; typedef short int i16; -typedef unsigned int uint; typedef unsigned int u32; typedef int i32; +typedef unsigned char bool; #endif \ No newline at end of file diff --git a/include/kernel/util.h b/include/kernel/util.h new file mode 100644 index 0000000..4823221 --- /dev/null +++ b/include/kernel/util.h @@ -0,0 +1,25 @@ +/* +Copyright 2022 Mattia Giambirtone & Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef TSOS_UTIL_H +#define TSOS_UTIL_H + +#include "kernel/types.h" + +void copystr(const char* source, char* dest, i32 n); +void itoa(i32 i, char* a); + +#endif \ No newline at end of file diff --git a/src/boot/mbr.s b/src/boot/mbr.s index 7fb7448..7a4b491 100644 --- a/src/boot/mbr.s +++ b/src/boot/mbr.s @@ -47,7 +47,7 @@ jmp $ ; Keeps jumping at the current address (loops forever) ; Here we define our variables: They need to be defined after the ; halting because otherwise they will be executed as code -real_mode_msg: db "TSOS is starting up", 0 +real_mode_msg: db "TSBL is starting up", 0 protected_mode_msg: db "Switched to protected mode", 0 loading_kernel_msg: db "Loading kernel into memory", 0 boot_drive: db 0 @@ -58,7 +58,7 @@ load_kernel: ; Loads the kernel into memory mov si, loading_kernel_msg call bios_println mov bx, kernel_offset - mov dh, 3 + mov dh, 4 mov dl, [boot_drive] call load_disk ret diff --git a/src/kernel/drivers/vga/screen.c b/src/kernel/drivers/vga/screen.c index e355f7f..e12d360 100644 --- a/src/kernel/drivers/vga/screen.c +++ b/src/kernel/drivers/vga/screen.c @@ -16,7 +16,8 @@ limitations under the License. // Implementation of a simple text-only VGA driver #include "kernel/drivers/vga/screen.h" -#include "kernel/ktypes.h" +#include "kernel/types.h" +#include "kernel/util.h" i32 getCursorOffset(void); @@ -82,12 +83,22 @@ i32 putchar(byte ch, i32 col, i32 row, byte attr) { - '\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 */ 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; + } i32 offset = (col >= 0 && row >= 0)? getOffset(col, row): getCursorOffset(); switch (ch) { // Note the difference between a carriage return (which @@ -112,6 +123,26 @@ i32 putchar(byte ch, i32 col, i32 row, byte attr) { offset += 2; break; } + // We check if we reached the end of the screen, in which + // case we scroll + if (offset >= SCREEN_SIZE * 2) { + for (i32 i = 1; i < MAX_ROWS; i ++) { + // This loop will take the bytes of row i and copy + // them to row i - 1, effectively erasing the first + // one and causing the text on the screen to scroll! + copystr((char *)(getOffset(0, i) + VMEM_ADDRESS), + (char*)(getOffset(0, i - 1) + VMEM_ADDRESS), + MAX_COLS * 2); + } + // We empty the last line + char* last = (char*)(getOffset(0, MAX_ROWS - 1) + VMEM_ADDRESS); + for (i32 i = 0; i < MAX_COLS * 2; i++) { + last[i] = 0; + } + + offset -= 2 * MAX_COLS; + } + setCursorOffset(offset); return offset; } diff --git a/src/kernel/main.c b/src/kernel/main.c index 18e45bb..035e111 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -14,13 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Entry point of the TSOS kernel -#include "kernel/ktypes.h" +#include "kernel/types.h" #include "kernel/drivers/vga/screen.h" +#include "kernel/util.h" void kmain(void) { + /* + The kernel entry point of TSOS + */ + // Newline so we skip the log // messages from the bootloader kprint("\nTSOS Kernel is starting up"); + // TODO: Sleep + clearScreen(); + char str[255]; + /* Fill up the screen */ + for (i32 i = 0; i < 24; i++) { + itoa(i, str); + kprintAt(str, 0, i); + } + + kprintAt("This text forces the kernel to scroll. Row 0 will disappear.", 60, 24); + kprint("\nAnd with this text, the kernel will scroll again, and row 1 will disappear too!"); } \ No newline at end of file diff --git a/src/kernel/util.c b/src/kernel/util.c new file mode 100644 index 0000000..e237d29 --- /dev/null +++ b/src/kernel/util.c @@ -0,0 +1,74 @@ +/* +Copyright 2022 Mattia Giambirtone & Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "kernel/types.h" +#include "kernel/util.h" + +void copystr(const char* restrict source, char* restrict dest, i32 n) { + /* + Copies n bytes from source to dest. The two memory locations may + not overlap: if they do, the behavior is undefined. This function's + behavior is also undefined if: + - n is larger than source's or dest's actual size + - dest is smaller than source + The caller should make sure these conditions are checked for before + calling this function + */ + int i; + for (i = 0; i < n; i++) { + *(dest + i) = *(source + i); + } +} + + +i32 countDigits(i32 n) { + /* + Returns the number of digits + of n + */ + i32 result = 0; + while (n) { + n /= 10; + result++; + } + return result; + +} + + +void itoa(i32 n, char* a) { + /* + Converts the integer n to + a string. The result is written + to a, which is assumed to be large + enough to accomodate an optional + negative sign, the number itself + and a null byte at the end (if the + buffer is not large enough, the + behavior is undefined) + */ + int i, sign; + if ((sign = n) < 0) n = -n; + i = countDigits(n); + do { + a[--i] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (sign < 0) a[--i] = '-'; + a[--i] = '\0'; + + /* TODO: implement "reverse" */ +} \ No newline at end of file