Renamed ktypes.h to types.h, added missing directories in make prepare, implemented text scrolling and added util module with a few test functions

This commit is contained in:
Nocturn9x 2022-11-18 01:20:51 +01:00
parent 5c9d280a92
commit 18f8b5c23f
10 changed files with 158 additions and 10 deletions

View File

@ -1,5 +1,6 @@
{
"files.associations": {
"ktypes.h": "c"
"ktypes.h": "c",
"ports.h": "c"
}
}

View File

@ -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:

View File

@ -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);

View File

@ -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"

View File

@ -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

25
include/kernel/util.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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!");
}

74
src/kernel/util.c Normal file
View File

@ -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" */
}